A powerful Model Context Protocol (MCP) server for GitLab integration, enabling AI assistants to interact with your GitLab resources.
npm install @yoda.digital/gitlab-mcp-server
# Clone the repository
git clone https://github.com/yoda-digital/mcp-gitlab-server.git
cd mcp-gitlab-server
# Install dependencies
npm install
# Build the project
npm run build
The server requires the following environment variables:
Variable | Required | Default | Description |
---|---|---|---|
GITLAB_PERSONAL_ACCESS_TOKEN | Yes | - | Your GitLab personal access token |
GITLAB_API_URL | No | https://gitlab.com/api/v4 | GitLab API URL |
PORT | No | 3000 | Port for SSE transport |
USE_SSE | No | false | Set to 'true' to use SSE transport |
GITLAB_READ_ONLY_MODE | No | false | Set to 'true' to enable read-only mode (see below) |
When GITLAB_READ_ONLY_MODE
is set to true
, the server will only expose read operations. This is useful for client applications that shouldn't have write access to your GitLab resources. In read-only mode, the following tools will be available:
search_repositories
get_file_contents
list_group_projects
get_project_events
list_commits
list_issues
list_merge_requests
list_project_wiki_pages
get_project_wiki_page
list_group_wiki_pages
get_group_wiki_page
list_project_members
list_group_members
Any attempt to use write operations (create, update, delete) will result in an error when in read-only mode.
Add the GitLab MCP server to your MCP settings file:
{
"mcpServers": {
"gitlab": {
"command": "npx",
"args": ["-y", "@yoda.digital/gitlab-mcp-server"],
"env": {
"GITLAB_PERSONAL_ACCESS_TOKEN": "your_token_here",
"GITLAB_API_URL": "https://gitlab.com/api/v4"
},
"alwaysAllow": [],
"disabled": false
}
}
}
For read-only mode, add the GITLAB_READ_ONLY_MODE
environment variable:
{
"mcpServers": {
"gitlab-readonly": {
"command": "npx",
"args": ["-y", "@yoda.digital/gitlab-mcp-server"],
"env": {
"GITLAB_PERSONAL_ACCESS_TOKEN": "your_token_here",
"GITLAB_API_URL": "https://gitlab.com/api/v4",
"GITLAB_READ_ONLY_MODE": "true"
},
"alwaysAllow": [],
"disabled": false
}
}
}
# Set your GitLab personal access token
export GITLAB_PERSONAL_ACCESS_TOKEN=your_token_here
# Run the server
npm start
# Set your GitLab personal access token and enable SSE
export GITLAB_PERSONAL_ACCESS_TOKEN=your_token_here
export GITLAB_READ_ONLY_MODE=false
export USE_SSE=true
export PORT=3000 # Optional, defaults to 3000
# Run the server
npm start
# Run directly with npx
GITLAB_PERSONAL_ACCESS_TOKEN=your_token_here npx @yoda.digital/gitlab-mcp-server
{
"search": "project-name",
"page": 1,
"per_page": 20
}
{
"name": "new-project",
"description": "A new project",
"visibility": "private",
"initialize_with_readme": true
}
{
"project_id": "username/project",
"namespace": "target-namespace"
}
{
"group_id": "group-name",
"archived": false,
"visibility": "public",
"include_subgroups": true,
"page": 1,
"per_page": 20
}
{
"project_id": "username/project",
"file_path": "path/to/file.txt",
"ref": "main"
}
{
"project_id": "username/project",
"file_path": "path/to/file.txt",
"content": "File content here",
"commit_message": "Add/update file",
"branch": "main",
"previous_path": "old/path/to/file.txt"
}
{
"project_id": "username/project",
"files": [
{
"path": "file1.txt",
"content": "Content for file 1"
},
{
"path": "file2.txt",
"content": "Content for file 2"
}
],
"commit_message": "Add multiple files",
"branch": "main"
}
{
"project_id": "username/project",
"branch": "new-branch",
"ref": "main"
}
{
"project_id": "username/project",
"title": "Issue title",
"description": "Issue description",
"assignee_ids": [1, 2],
"milestone_id": 1,
"labels": ["bug", "critical"]
}
{
"project_id": "username/project",
"state": "opened",
"labels": "bug,critical",
"milestone": "v1.0",
"author_id": 1,
"assignee_id": 2,
"search": "keyword",
"created_after": "2023-01-01T00:00:00Z",
"created_before": "2023-12-31T23:59:59Z",
"updated_after": "2023-06-01T00:00:00Z",
"updated_before": "2023-06-30T23:59:59Z",
"page": 1,
"per_page": 20
}
{
"project_id": "username/project",
"issue_iid": 42,
"sort": "desc",
"order_by": "created_at",
"page": 1,
"per_page": 20
}
Response Format:
{
"count": 15,
"notes": [
{
"id": 123456,
"body": "This is a comment on the issue",
"author": {
"id": 1,
"username": "username",
"name": "User Name"
},
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z",
"system": false,
"type": "comment"
},
{
"id": 123457,
"body": "added label ~bug",
"author": {
"id": 1,
"username": "username",
"name": "User Name"
},
"created_at": "2023-01-02T00:00:00Z",
"updated_at": "2023-01-02T00:00:00Z",
"system": true,
"type": "system"
}
// ... other notes
]
}
{
"project_id": "username/project",
"issue_iid": 42,
"page": 1,
"per_page": 20
}
Response Format:
{
"count": 5,
"discussions": [
{
"id": "discussion-123",
"individual_note": true,
"notes": [
{
"id": 123456,
"body": "This is a comment on the issue",
"author": {
"id": 1,
"username": "username",
"name": "User Name"
},
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z",
"system": false,
"type": "comment"
}
]
},
{
"id": "discussion-124",
"individual_note": false,
"notes": [
{
"id": 123457,
"body": "This is a thread starter",
"author": {
"id": 1,
"username": "username",
"name": "User Name"
},
"created_at": "2023-01-02T00:00:00Z",
"updated_at": "2023-01-02T00:00:00Z",
"system": false,
"type": "comment"
},
{
"id": 123458,
"body": "This is a reply in the thread",
"author": {
"id": 2,
"username": "username2",
"name": "User Name 2"
},
"created_at": "2023-01-03T00:00:00Z",
"updated_at": "2023-01-03T00:00:00Z",
"system": false,
"type": "comment"
}
]
}
// ... other discussions
]
}
{
"project_id": "username/project",
"title": "Merge request title",
"description": "Merge request description",
"source_branch": "feature-branch",
"target_branch": "main",
"allow_collaboration": true,
"draft": false
}
{
"project_id": "username/project",
"state": "opened",
"order_by": "created_at",
"sort": "desc",
"milestone": "v1.0",
"labels": "feature,enhancement",
"created_after": "2023-01-01T00:00:00Z",
"created_before": "2023-12-31T23:59:59Z",
"updated_after": "2023-06-01T00:00:00Z",
"updated_before": "2023-06-30T23:59:59Z",
"author_id": 1,
"assignee_id": 2,
"search": "keyword",
"source_branch": "feature-branch",
"target_branch": "main",
"page": 1,
"per_page": 20
}
{
"project_id": "username/project",
"action": "pushed",
"target_type": "issue",
"before": "2023-12-31T23:59:59Z",
"after": "2023-01-01T00:00:00Z",
"sort": "desc",
"page": 1,
"per_page": 20
}
{
"project_id": "username/project",
"sha": "branch-or-commit-sha",
"path": "path/to/file",
"since": "2023-01-01T00:00:00Z",
"until": "2023-12-31T23:59:59Z",
"all": true,
"with_stats": true,
"first_parent": true,
"page": 1,
"per_page": 20
}
{
"project_id": "username/project",
"query": "search term",
"page": 1,
"per_page": 20
}
Response Format:
{
"count": 3,
"items": [
{
"id": 123,
"username": "username",
"name": "User Name",
"state": "active",
"avatar_url": "https://gitlab.com/avatar.png",
"web_url": "https://gitlab.com/username",
"access_level": 50,
"access_level_description": "Owner"
}
// ... other members
]
}
{
"group_id": "group-name",
"query": "search term",
"page": 1,
"per_page": 20
}
Response Format:
{
"count": 5,
"items": [
{
"id": 456,
"username": "username",
"name": "User Name",
"state": "active",
"avatar_url": "https://gitlab.com/avatar.png",
"web_url": "https://gitlab.com/username",
"access_level": 30,
"access_level_description": "Developer"
}
// ... other members
]
}
{
"project_id": "username/project",
"with_content": false
}
{
"project_id": "username/project",
"slug": "page-slug",
"render_html": false,
"version": "commit-sha"
}
{
"project_id": "username/project",
"title": "Page Title",
"content": "Wiki page content",
"format": "markdown"
}
{
"project_id": "username/project",
"slug": "page-slug",
"title": "New Page Title",
"content": "Updated wiki page content",
"format": "markdown"
}
{
"project_id": "username/project",
"slug": "page-slug"
}
{
"project_id": "username/project",
"file_path": "path/to/attachment.png",
"content": "base64-encoded-content",
"branch": "main"
}
{
"group_id": "group-name",
"with_content": false
}
{
"group_id": "group-name",
"slug": "page-slug",
"render_html": false,
"version": "commit-sha"
}
{
"group_id": "group-name",
"title": "Page Title",
"content": "Wiki page content",
"format": "markdown"
}
{
"group_id": "group-name",
"slug": "page-slug",
"title": "New Page Title",
"content": "Updated wiki page content",
"format": "markdown"
}
{
"group_id": "group-name",
"slug": "page-slug"
}
{
"group_id": "group-name",
"file_path": "path/to/attachment.png",
"content": "base64-encoded-content",
"branch": "main"
}
npm run build
npm test
npm run lint
package.json
npm publish
For more detailed documentation, please visit our documentation site or check the TypeScript definitions in the source code.
Contributions are welcome and appreciated! Here's how you can contribute:
git checkout -b feature/amazing-feature
)git commit -m 'Add some amazing feature'
)git push origin feature/amazing-feature
)Please make sure to update tests as appropriate and follow the code style of the project.
This project is licensed under the MIT License - see the LICENSE file for details.
Thanks to all the contributors who have helped improve this project:
Special thanks to:
This package is available on npm:
https://www.npmjs.com/package/@yoda.digital/gitlab-mcp-server
Seamless access to top MCP servers powering the future of AI integration.