Skip to content

Commit 47bafbd

Browse files
authored
Merge pull request #2 from redhat-ai-tools/use-makefile
Use makefile for quick setup
2 parents 6e1effb + 9e0e5a6 commit 47bafbd

13 files changed

+509
-84
lines changed

.containerignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.env
2+
.venv
3+
__pycache__
4+
*.pyc

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.env
2+
.vscode

Containerfile

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
1-
FROM registry.redhat.io/ubi9/python-311
1+
FROM python:3.11-slim
22

3-
# Set working directory
3+
# Set work directory
44
WORKDIR /app
55

6-
# Copy requirements first for better caching
7-
COPY requirements.txt .
8-
9-
# Install Python dependencies
6+
# Install dependencies
7+
COPY requirements.txt ./
108
RUN pip install --no-cache-dir -r requirements.txt
119

12-
# Copy server code
13-
COPY gitlab_mcp_server.py .
14-
15-
# Set environment variables
16-
ENV MCP_TRANSPORT=stdio
17-
ENV PYTHONPATH=/app
10+
# Copy source code (uses .containerignore)
11+
COPY . .
1812

19-
# Run the MCP server
20-
CMD ["python", "gitlab_mcp_server.py"]
13+
# Entrypoint
14+
CMD ["python", "gitlab_mcp_server.py"]

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) Red Hat, Inc.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Makefile

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
2+
_default: run
3+
4+
SHELL := /bin/bash
5+
SCRIPT_DIR := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
6+
IMG := localhost/gitlab-mcp:latest
7+
ENV_FILE := $(HOME)/.rh-gitlab-mcp.env
8+
9+
.PHONY: build run clean test cursor-config setup
10+
11+
build:
12+
@echo "🛠️ Building GitLab MCP server image"
13+
podman build -t $(IMG) .
14+
15+
# Notes:
16+
# - $(ENV_FILE) is expected to define the gitlab token & repos other vars are optional.
17+
# - This server runs in STDIO mode for MCP clients like Cursor.
18+
# - Use Ctrl-C to quit the server.
19+
run:
20+
@echo "🚀 Starting GitLab MCP server (STDIO mode)"
21+
@podman run -i --rm --env-file $(ENV_FILE) $(IMG)
22+
23+
clean:
24+
podman rmi -i $(IMG)
25+
26+
# For easier onboarding (and convenient hacking and testing), use this to
27+
# configure Cursor by adding or updating an entry in the ~/.cursor/mcp.json
28+
# file. Beware it might overwrite your customizations.
29+
MCP_JSON=$(HOME)/.cursor/mcp.json
30+
cursor-config:
31+
@echo "🛠️ Modifying $(MCP_JSON)"
32+
@yq -ojson '. *= load("example.mcp.json")' -i $(MCP_JSON)
33+
@yq -ojson $(MCP_JSON)
34+
35+
# Copy the example .env file only if it doesn't exist already
36+
$(ENV_FILE):
37+
@cp example.env $@
38+
@echo "🛠️ Env file created. Edit $@ to add your GitLab token"
39+
40+
setup: build cursor-config $(ENV_FILE)

README.md

Lines changed: 173 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,207 @@
11
# gitlab-mcp-server
22

3-
Gitlab MCP (ModelContextProvider) server
3+
Gitlab MCP (ModelContextProvider) server is a containerized Python MCP server for Cursor to provide access to GitLab API(read-only as of now).
44

55
---
66

77
## 📦 Installation
88

99
### Prerequisites
1010

11-
- Python 3.11 or higher
12-
- Running MCP server(s)
1311
- Cursor as MCP client
1412
- Podman(If running as containers)
1513

16-
### Method 1: local setup in venv
14+
## Quick Start
1715

16+
1. **Get the code**
1817
```bash
1918
git clone [email protected]:redhat-ai-tools/gitlab-mcp.git
2019
cd gitlab-mcp
21-
python3 -m venv venv
22-
source venv/bin/activate
23-
pip install -r requirements.txt
2420
```
25-
Set MCP env vars, if not set everything else will fallback to default except MCP_GITLAB_TOKEN.
26-
If everything is set, Test this setup using:
27-
```
28-
python gitlab_mcp_server.py
29-
INFO:__main__:🔒 Max API calls/hour: 100
30-
INFO:__main__:🔒 Allowed actions: ['read']
31-
INFO:__main__:🔒 Allowed repos: [<your allowed repo list>]
32-
INFO:__main__:🔗 GitLab URL: <if gitlab URL is provided it will show up here, else the default value will appear>
33-
🚀 Starting GitLab MCP Server (FastMCP - Read-Only)...
34-
📋 Available Tools:
35-
🔍 search_repositories - Search/filter repositories
36-
📋 list_issues - List project issues
37-
🔀 list_merge_requests - List merge requests
38-
🏗️ list_pipelines - List CI/CD pipelines
39-
⚙️ list_jobs - List pipeline jobs
40-
❌ check_latest_failed_jobs - Check failed jobs
41-
📝 list_latest_commits - List recent commits
21+
22+
2. **Build the image & configure Cursor**<br>
23+
This also creates a `~/.rh-gitlab-mcp.env` file like [this](example.env).
24+
```bash
25+
make setup
4226
```
43-
Interrupt Ctrl+C, and add this to Cursor config as shown in next steps.
4427

45-
## Running locally in a MCP client like cursor
28+
3. **Prepare a GitLab token**
29+
* Go to ${GITLAB_URL} if no custom gitlab defaults to public [gitlab.com](https://docs.gitlab.com/user/profile/personal_access_tokens/) and create a token
30+
* Edit the `.rh-gitlab-mcp.env` file in your home directory and paste in the token.
31+
32+
To confirm it's working, run Cursor, go to Settings and click on "Tools & Integrations". Under MCP Tools you should see "gitlabMcp" with 8 tools enabled.
33+
34+
35+
## Available Functions
36+
37+
### 🔍 Search & Discovery
38+
- `search_repositories` - Find projects by name, description, or path
39+
- `list_issues` - List issues in a project
40+
- `list_merge_requests` - List merge requests in a project
41+
- `list_pipelines` - List pipelines in a project
42+
- `list_jobs` - List jobs in a specific pipeline
43+
44+
### 📊 Monitoring & Analysis
45+
- `check_latest_failed_jobs` - Find recent failed jobs across pipelines
46+
- `list_latest_commits` - View recent commits in projects
47+
48+
## Correct Query Patterns
49+
50+
### For Project Discovery
51+
**Correct Prompts:**
52+
- "Search for projects containing 'systemd'"
53+
- "Find repositories with 'kernel' in the name"
54+
- "List my owned projects"
55+
- "Show all public repositories"
56+
57+
**Avoid:**
58+
- Single word searches without context
59+
- Vague terms like "find stuff"
60+
61+
### For Failed Jobs Analysis
62+
**Correct Prompts:**
63+
- "List the failed jobs in mcp-servers project"
64+
- "Show recent failed jobs for project ID 123"
65+
- "Find failed pipeline jobs in the last few runs"
66+
67+
**Avoid:**
68+
- Just saying "failed jobs" without specifying project
4669

47-
To run this MCP server from cursor. Go to cursor settings -> Tools & integrations -> Add MCP server
70+
### For Project Monitoring
71+
**Correct Prompts:**
72+
- "Show recent pipelines for project 456"
73+
- "List open issues in my-project"
74+
- "Show merge requests waiting for review in project XYZ"
75+
- "Get latest commits from all my projects"
76+
77+
## Step by step example:
78+
79+
When you ask: **"List the failed jobs in mcp-servers project"**
80+
81+
The MCP follows:
82+
1. 🔍 **Search for project:** Use `search_repositories` with search_term="mcp-servers"
83+
2. 📋 **Get project ID:** Extract the project ID from search results
84+
3.**List failed jobs:** Use `check_latest_failed_jobs` with that project ID
85+
4. 📊 **Display results:** Show the recent failed jobs with details
86+
87+
## Function Details
88+
89+
### search_repositories
90+
```json
91+
{
92+
"search_term": "mcp-servers", // Optional: project name/description
93+
"visibility": "all", // public, private, internal, all
94+
"owned": false, // true for only owned repos
95+
"limit": 10 // max results
96+
}
97+
```
98+
99+
### check_latest_failed_jobs
100+
```json
101+
{
102+
"project_id": "123", // Required: GitLab project ID
103+
"limit": 5 // Optional: max failed jobs to return
104+
}
105+
```
48106

107+
### list_issues
49108
```json
50109
{
51-
"mcpServers": {
52-
"gitlab-mcp-local": {
53-
"command": "<venv absolute path>/python",
54-
"args": ["<git clone dir path>/gitlab_mcp_server.py"],
55-
"env": {
56-
"MCP_GITLAB_TOKEN": "your-actual-token-here",
57-
"MCP_ALLOWED_REPOS": "list of comma separated repos or groups with wildcard",
58-
"GITLAB_URL": "https://gitlab.com" ## <-this is optional var but if you want to explicitly set to some gitlab instance pass here
59-
},
60-
"trust": true
61-
}
62-
}
110+
"project_id": "123", // Required: GitLab project ID
111+
"state": "opened", // opened, closed, all
112+
"limit": 20 // max results
113+
}
114+
```
115+
116+
### list_pipelines
117+
```json
118+
{
119+
"project_id": "123", // Required: GitLab project ID
120+
"status": "all", // running, pending, success, failed, all
121+
"limit": 20 // max results
63122
}
64123
```
65124

66-
### Method 2: Container build
125+
## Security Features
126+
127+
-**Rate limiting:** Max 100 API calls per hour (configurable)
128+
-**Action restrictions:** Only "read" actions allowed by default
129+
-**Repository access control:** Configurable repo allowlist
130+
-**Error handling:** Graceful failures with helpful messages
131+
132+
## Environment Configuration
67133

68134
```bash
69-
git clone [email protected]:redhat-ai-tools/gitlab-mcp.git
70-
cd gitlab-mcp
71-
podman build -t gitlab-mcp-server:latest .
135+
# Required
136+
export MCP_GITLAB_TOKEN="your-gitlab-token"
137+
138+
# Optional
139+
export GITLAB_URL="https://gitlab.example.com"
140+
export MCP_MAX_API_CALLS="100"
141+
export MCP_ALLOWED_ACTIONS="read"
142+
export MCP_ALLOWED_REPOS="project1,project2" # Empty = all allowed
72143
```
73144

74-
This will create a local image named `gitlab-mcp-server:latest` that you can use to run the server.
145+
## Example Workflows
75146

76-
## Running with Podman or Docker
147+
### 1. Investigate Failed Jobs
148+
```
149+
Human: "List failed jobs in mcp-tests project"
150+
→ MCP searches for "mcp-tests" project
151+
→ MCP gets project ID from search results
152+
→ MCP lists recent failed jobs with details
153+
```
77154

78-
Example configuration for running with Podman:
155+
### 2. Project Health Check
156+
```
157+
Human: "Show pipeline status for my-app project"
158+
→ MCP searches for "my-app" project
159+
→ MCP lists recent pipelines with status
160+
→ Human can drill down into specific pipelines
161+
```
79162

80-
```json
81-
{
82-
"mcpServers": {
83-
"gitlab-mcp-server": {
84-
"command": "podman",
85-
"args": [
86-
"run",
87-
"-i",
88-
"--rm",
89-
"--env", "MCP_GITLAB_URL", ## <-- if this is not passed, it will fallback to default gitlab.com
90-
"--env", "MCP_GITLAB_TOKEN",
91-
"--env","MCP_ALLOWED_REPOS",
92-
"localhost/gitlab-mcp-server:latest"
93-
],
94-
}
95-
}
96-
}
163+
### 3. Issue Tracking
97164
```
165+
Human: "What open issues are there in frontend-app?"
166+
→ MCP searches for "frontend-app" project
167+
→ MCP lists open issues with assignees and dates
168+
```
169+
170+
## Best Practices
171+
172+
### 🎯 Be Specific
173+
- Include project names in queries
174+
- Specify what information you want (issues, MRs, pipelines, etc.)
175+
- Use descriptive terms rather than abbreviations
176+
177+
### 🔄 Multi-Step Queries
178+
The MCP can now handle complex queries that require multiple steps:
179+
1. Search for project by name
180+
2. Get specific information about that project
181+
3. Drill down into details as needed
182+
183+
### 📊 Use Filters
184+
Most functions support filtering:
185+
- **States:** opened, closed, merged, failed, success
186+
- **Limits:** Control result size for performance
187+
- **Visibility:** Focus on relevant repositories
188+
189+
## Troubleshooting
190+
191+
### Common Issues
192+
193+
**🚫 "Project not found"**
194+
- Try broader search terms
195+
- Check if you have access to the project
196+
- Verify project name spelling
197+
198+
**🚫 "Rate limit exceeded"**
199+
- Wait an hour for limit reset
200+
- Increase `MCP_MAX_API_CALLS` if needed
201+
202+
**🚫 "Access denied"**
203+
- Check `MCP_ALLOWED_REPOS` configuration
204+
- Verify your GitLab token has proper permissions
205+
- Ensure you're a project member
206+
207+
This read-only approach provides safer, more focused GitLab integration for monitoring and analysis workflows.

0 commit comments

Comments
 (0)