mcp-gitlab-crunchtools 0.1.0__tar.gz
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.
- mcp_gitlab_crunchtools-0.1.0/.github/workflows/ci.yml +53 -0
- mcp_gitlab_crunchtools-0.1.0/.github/workflows/container.yml +67 -0
- mcp_gitlab_crunchtools-0.1.0/.github/workflows/publish.yml +29 -0
- mcp_gitlab_crunchtools-0.1.0/.github/workflows/security.yml +140 -0
- mcp_gitlab_crunchtools-0.1.0/.gitignore +90 -0
- mcp_gitlab_crunchtools-0.1.0/CLAUDE.md +153 -0
- mcp_gitlab_crunchtools-0.1.0/Containerfile +44 -0
- mcp_gitlab_crunchtools-0.1.0/LICENSE +661 -0
- mcp_gitlab_crunchtools-0.1.0/PKG-INFO +291 -0
- mcp_gitlab_crunchtools-0.1.0/README.md +265 -0
- mcp_gitlab_crunchtools-0.1.0/SECURITY.md +221 -0
- mcp_gitlab_crunchtools-0.1.0/pyproject.toml +75 -0
- mcp_gitlab_crunchtools-0.1.0/src/mcp_gitlab_crunchtools/__init__.py +60 -0
- mcp_gitlab_crunchtools-0.1.0/src/mcp_gitlab_crunchtools/__main__.py +6 -0
- mcp_gitlab_crunchtools-0.1.0/src/mcp_gitlab_crunchtools/client.py +239 -0
- mcp_gitlab_crunchtools-0.1.0/src/mcp_gitlab_crunchtools/config.py +133 -0
- mcp_gitlab_crunchtools-0.1.0/src/mcp_gitlab_crunchtools/errors.py +66 -0
- mcp_gitlab_crunchtools-0.1.0/src/mcp_gitlab_crunchtools/models.py +231 -0
- mcp_gitlab_crunchtools-0.1.0/src/mcp_gitlab_crunchtools/server.py +992 -0
- mcp_gitlab_crunchtools-0.1.0/src/mcp_gitlab_crunchtools/tools/__init__.py +87 -0
- mcp_gitlab_crunchtools-0.1.0/src/mcp_gitlab_crunchtools/tools/groups.py +119 -0
- mcp_gitlab_crunchtools-0.1.0/src/mcp_gitlab_crunchtools/tools/issues.py +254 -0
- mcp_gitlab_crunchtools-0.1.0/src/mcp_gitlab_crunchtools/tools/merge_requests.py +296 -0
- mcp_gitlab_crunchtools-0.1.0/src/mcp_gitlab_crunchtools/tools/pipelines.py +251 -0
- mcp_gitlab_crunchtools-0.1.0/src/mcp_gitlab_crunchtools/tools/projects.py +164 -0
- mcp_gitlab_crunchtools-0.1.0/src/mcp_gitlab_crunchtools/tools/search.py +89 -0
- mcp_gitlab_crunchtools-0.1.0/tests/__init__.py +1 -0
- mcp_gitlab_crunchtools-0.1.0/tests/test_tools.py +812 -0
- mcp_gitlab_crunchtools-0.1.0/tests/test_validation.py +232 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
python-version: ["3.10", "3.11", "3.12"]
|
|
15
|
+
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@v4
|
|
21
|
+
with:
|
|
22
|
+
version: "latest"
|
|
23
|
+
|
|
24
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
25
|
+
run: uv python install ${{ matrix.python-version }}
|
|
26
|
+
|
|
27
|
+
- name: Install dependencies
|
|
28
|
+
run: uv sync --all-extras
|
|
29
|
+
|
|
30
|
+
- name: Run linter
|
|
31
|
+
run: uv run ruff check src tests
|
|
32
|
+
|
|
33
|
+
- name: Run type checker
|
|
34
|
+
run: uv run mypy src
|
|
35
|
+
|
|
36
|
+
- name: Run tests
|
|
37
|
+
run: uv run pytest -v
|
|
38
|
+
env:
|
|
39
|
+
GITLAB_TOKEN: "test_token_for_ci"
|
|
40
|
+
|
|
41
|
+
build-container:
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
steps:
|
|
44
|
+
- uses: actions/checkout@v4
|
|
45
|
+
|
|
46
|
+
- name: Build container image
|
|
47
|
+
run: |
|
|
48
|
+
docker build -f Containerfile -t mcp-gitlab:test .
|
|
49
|
+
|
|
50
|
+
- name: Verify container
|
|
51
|
+
run: |
|
|
52
|
+
# Just verify it starts (will fail due to no token, but should start)
|
|
53
|
+
timeout 5 docker run --rm mcp-gitlab:test || true
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
name: Container Build & Push
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
tags: ["v*"]
|
|
7
|
+
pull_request:
|
|
8
|
+
branches: [main]
|
|
9
|
+
workflow_dispatch:
|
|
10
|
+
|
|
11
|
+
env:
|
|
12
|
+
REGISTRY: quay.io
|
|
13
|
+
IMAGE_NAME: crunchtools/mcp-gitlab
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
build-and-push:
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
permissions:
|
|
19
|
+
contents: read
|
|
20
|
+
packages: write
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- name: Checkout repository
|
|
24
|
+
uses: actions/checkout@v4
|
|
25
|
+
|
|
26
|
+
- name: Set up Docker Buildx
|
|
27
|
+
uses: docker/setup-buildx-action@v3
|
|
28
|
+
|
|
29
|
+
- name: Log in to Quay.io
|
|
30
|
+
if: github.event_name != 'pull_request'
|
|
31
|
+
uses: docker/login-action@v3
|
|
32
|
+
with:
|
|
33
|
+
registry: ${{ env.REGISTRY }}
|
|
34
|
+
username: ${{ secrets.QUAY_USERNAME }}
|
|
35
|
+
password: ${{ secrets.QUAY_PASSWORD }}
|
|
36
|
+
|
|
37
|
+
- name: Extract metadata (tags, labels)
|
|
38
|
+
id: meta
|
|
39
|
+
uses: docker/metadata-action@v5
|
|
40
|
+
with:
|
|
41
|
+
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
|
42
|
+
tags: |
|
|
43
|
+
type=ref,event=branch
|
|
44
|
+
type=ref,event=pr
|
|
45
|
+
type=semver,pattern={{version}}
|
|
46
|
+
type=semver,pattern={{major}}.{{minor}}
|
|
47
|
+
type=raw,value=latest,enable={{is_default_branch}}
|
|
48
|
+
|
|
49
|
+
- name: Build and push container image
|
|
50
|
+
uses: docker/build-push-action@v6
|
|
51
|
+
with:
|
|
52
|
+
context: .
|
|
53
|
+
file: ./Containerfile
|
|
54
|
+
push: ${{ github.event_name != 'pull_request' }}
|
|
55
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
56
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
57
|
+
cache-from: type=gha
|
|
58
|
+
cache-to: type=gha,mode=max
|
|
59
|
+
|
|
60
|
+
- name: Run Trivy vulnerability scanner
|
|
61
|
+
if: github.event_name != 'pull_request'
|
|
62
|
+
uses: aquasecurity/trivy-action@master
|
|
63
|
+
with:
|
|
64
|
+
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
|
|
65
|
+
format: "table"
|
|
66
|
+
exit-code: "0"
|
|
67
|
+
severity: "CRITICAL,HIGH"
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
publish:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
permissions:
|
|
12
|
+
id-token: write # Required for trusted publishing
|
|
13
|
+
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Install uv
|
|
18
|
+
uses: astral-sh/setup-uv@v4
|
|
19
|
+
with:
|
|
20
|
+
version: "latest"
|
|
21
|
+
|
|
22
|
+
- name: Set up Python
|
|
23
|
+
run: uv python install 3.12
|
|
24
|
+
|
|
25
|
+
- name: Build package
|
|
26
|
+
run: uv build
|
|
27
|
+
|
|
28
|
+
- name: Publish to PyPI
|
|
29
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
name: Security Scan
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
schedule:
|
|
9
|
+
# Run every Monday at 9 AM UTC
|
|
10
|
+
- cron: "0 9 * * 1"
|
|
11
|
+
workflow_dispatch:
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
issues: write
|
|
16
|
+
pull-requests: write
|
|
17
|
+
security-events: write
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
dependency-audit:
|
|
21
|
+
name: Dependency CVE Scan
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
|
|
27
|
+
- name: Install uv
|
|
28
|
+
uses: astral-sh/setup-uv@v4
|
|
29
|
+
with:
|
|
30
|
+
version: "latest"
|
|
31
|
+
|
|
32
|
+
- name: Set up Python
|
|
33
|
+
run: uv python install 3.12
|
|
34
|
+
|
|
35
|
+
- name: Install dependencies
|
|
36
|
+
run: uv sync
|
|
37
|
+
|
|
38
|
+
- name: Install pip-audit
|
|
39
|
+
run: uv pip install pip-audit
|
|
40
|
+
|
|
41
|
+
- name: Run pip-audit
|
|
42
|
+
id: audit
|
|
43
|
+
continue-on-error: true
|
|
44
|
+
run: |
|
|
45
|
+
uv run pip-audit --format=json --output=audit-results.json || true
|
|
46
|
+
uv run pip-audit --format=markdown --output=audit-results.md || true
|
|
47
|
+
|
|
48
|
+
# Check if there are vulnerabilities
|
|
49
|
+
if [ -f audit-results.json ]; then
|
|
50
|
+
VULN_COUNT=$(cat audit-results.json | python -c "import sys,json; data=json.load(sys.stdin); print(len([d for d in data if d.get('vulns', [])]))" 2>/dev/null || echo "0")
|
|
51
|
+
echo "vuln_count=$VULN_COUNT" >> $GITHUB_OUTPUT
|
|
52
|
+
else
|
|
53
|
+
echo "vuln_count=0" >> $GITHUB_OUTPUT
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
- name: Upload audit results
|
|
57
|
+
if: always()
|
|
58
|
+
uses: actions/upload-artifact@v4
|
|
59
|
+
with:
|
|
60
|
+
name: security-audit-results
|
|
61
|
+
path: |
|
|
62
|
+
audit-results.json
|
|
63
|
+
audit-results.md
|
|
64
|
+
retention-days: 30
|
|
65
|
+
|
|
66
|
+
- name: Create issue for vulnerabilities
|
|
67
|
+
if: steps.audit.outputs.vuln_count != '0' && github.event_name == 'schedule'
|
|
68
|
+
uses: actions/github-script@v7
|
|
69
|
+
with:
|
|
70
|
+
script: |
|
|
71
|
+
const fs = require('fs');
|
|
72
|
+
let body = '## Security Vulnerabilities Detected\n\n';
|
|
73
|
+
body += 'The weekly security scan found vulnerabilities in project dependencies.\n\n';
|
|
74
|
+
|
|
75
|
+
if (fs.existsSync('audit-results.md')) {
|
|
76
|
+
body += fs.readFileSync('audit-results.md', 'utf8');
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
body += '\n\n### Action Required\n';
|
|
80
|
+
body += '1. Review the vulnerabilities listed above\n';
|
|
81
|
+
body += '2. Update affected dependencies\n';
|
|
82
|
+
body += '3. Run `uv sync` and test\n';
|
|
83
|
+
body += '4. Create a PR with the fixes\n';
|
|
84
|
+
|
|
85
|
+
await github.rest.issues.create({
|
|
86
|
+
owner: context.repo.owner,
|
|
87
|
+
repo: context.repo.repo,
|
|
88
|
+
title: `Security Alert: CVEs found in dependencies (${new Date().toISOString().split('T')[0]})`,
|
|
89
|
+
body: body,
|
|
90
|
+
labels: ['security', 'dependencies']
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
- name: Fail on vulnerabilities (PRs only)
|
|
94
|
+
if: steps.audit.outputs.vuln_count != '0' && github.event_name == 'pull_request'
|
|
95
|
+
run: |
|
|
96
|
+
echo "::error::Security vulnerabilities found in dependencies. See audit results."
|
|
97
|
+
exit 1
|
|
98
|
+
|
|
99
|
+
container-scan:
|
|
100
|
+
name: Container Security Scan
|
|
101
|
+
runs-on: ubuntu-latest
|
|
102
|
+
|
|
103
|
+
steps:
|
|
104
|
+
- uses: actions/checkout@v4
|
|
105
|
+
|
|
106
|
+
- name: Build container image
|
|
107
|
+
run: |
|
|
108
|
+
docker build -f Containerfile -t mcp-gitlab:scan .
|
|
109
|
+
|
|
110
|
+
- name: Run Trivy vulnerability scanner
|
|
111
|
+
uses: aquasecurity/trivy-action@master
|
|
112
|
+
with:
|
|
113
|
+
image-ref: "mcp-gitlab:scan"
|
|
114
|
+
format: "sarif"
|
|
115
|
+
output: "trivy-results.sarif"
|
|
116
|
+
severity: "CRITICAL,HIGH"
|
|
117
|
+
|
|
118
|
+
- name: Upload Trivy scan results
|
|
119
|
+
uses: github/codeql-action/upload-sarif@v3
|
|
120
|
+
if: always()
|
|
121
|
+
with:
|
|
122
|
+
sarif_file: "trivy-results.sarif"
|
|
123
|
+
|
|
124
|
+
codeql:
|
|
125
|
+
name: CodeQL Analysis
|
|
126
|
+
runs-on: ubuntu-latest
|
|
127
|
+
|
|
128
|
+
steps:
|
|
129
|
+
- uses: actions/checkout@v4
|
|
130
|
+
|
|
131
|
+
- name: Initialize CodeQL
|
|
132
|
+
uses: github/codeql-action/init@v3
|
|
133
|
+
with:
|
|
134
|
+
languages: python
|
|
135
|
+
queries: security-extended
|
|
136
|
+
|
|
137
|
+
- name: Perform CodeQL Analysis
|
|
138
|
+
uses: github/codeql-action/analyze@v3
|
|
139
|
+
with:
|
|
140
|
+
category: "/language:python"
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
*.manifest
|
|
31
|
+
*.spec
|
|
32
|
+
|
|
33
|
+
# Installer logs
|
|
34
|
+
pip-log.txt
|
|
35
|
+
pip-delete-this-directory.txt
|
|
36
|
+
|
|
37
|
+
# Unit test / coverage reports
|
|
38
|
+
htmlcov/
|
|
39
|
+
.tox/
|
|
40
|
+
.nox/
|
|
41
|
+
.coverage
|
|
42
|
+
.coverage.*
|
|
43
|
+
.cache
|
|
44
|
+
nosetests.xml
|
|
45
|
+
coverage.xml
|
|
46
|
+
*.cover
|
|
47
|
+
*.py,cover
|
|
48
|
+
.hypothesis/
|
|
49
|
+
.pytest_cache/
|
|
50
|
+
cover/
|
|
51
|
+
|
|
52
|
+
# Translations
|
|
53
|
+
*.mo
|
|
54
|
+
*.pot
|
|
55
|
+
|
|
56
|
+
# Environments
|
|
57
|
+
.env
|
|
58
|
+
.venv
|
|
59
|
+
env/
|
|
60
|
+
venv/
|
|
61
|
+
ENV/
|
|
62
|
+
env.bak/
|
|
63
|
+
venv.bak/
|
|
64
|
+
|
|
65
|
+
# IDE
|
|
66
|
+
.idea/
|
|
67
|
+
.vscode/
|
|
68
|
+
*.swp
|
|
69
|
+
*.swo
|
|
70
|
+
*~
|
|
71
|
+
|
|
72
|
+
# mypy
|
|
73
|
+
.mypy_cache/
|
|
74
|
+
.dmypy.json
|
|
75
|
+
dmypy.json
|
|
76
|
+
|
|
77
|
+
# ruff
|
|
78
|
+
.ruff_cache/
|
|
79
|
+
|
|
80
|
+
# uv
|
|
81
|
+
.uv/
|
|
82
|
+
uv.lock
|
|
83
|
+
|
|
84
|
+
# Local development
|
|
85
|
+
.envrc
|
|
86
|
+
.direnv/
|
|
87
|
+
|
|
88
|
+
# OS files
|
|
89
|
+
.DS_Store
|
|
90
|
+
Thumbs.db
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Claude Code Instructions
|
|
2
|
+
|
|
3
|
+
This is a secure MCP server for GitLab projects, merge requests, issues, pipelines, and search. Works with any GitLab instance (gitlab.com, self-hosted, or enterprise).
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
### Option 1: Using uvx (Recommended)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
claude mcp add mcp-gitlab-crunchtools \
|
|
11
|
+
--env GITLAB_TOKEN=your_token_here \
|
|
12
|
+
-- uvx mcp-gitlab-crunchtools
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### Option 2: Using Container
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
claude mcp add mcp-gitlab-crunchtools \
|
|
19
|
+
--env GITLAB_TOKEN=your_token_here \
|
|
20
|
+
-- podman run -i --rm -e GITLAB_TOKEN quay.io/crunchtools/mcp-gitlab
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Option 3: Self-Hosted GitLab
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
claude mcp add mcp-gitlab-crunchtools \
|
|
27
|
+
--env GITLAB_TOKEN=your_token_here \
|
|
28
|
+
--env GITLAB_URL=https://gitlab.example.com \
|
|
29
|
+
-- uvx mcp-gitlab-crunchtools
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Option 4: Local Development
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
cd ~/Projects/crunchtools/mcp-gitlab
|
|
36
|
+
claude mcp add mcp-gitlab-crunchtools \
|
|
37
|
+
--env GITLAB_TOKEN=your_token_here \
|
|
38
|
+
-- uv run mcp-gitlab-crunchtools
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Creating a GitLab Personal Access Token
|
|
42
|
+
|
|
43
|
+
### Step-by-Step Instructions
|
|
44
|
+
|
|
45
|
+
1. **Log in to your GitLab instance**
|
|
46
|
+
- Go to https://gitlab.com (or your self-hosted URL)
|
|
47
|
+
- Sign in with your account
|
|
48
|
+
|
|
49
|
+
2. **Navigate to Access Tokens**
|
|
50
|
+
- Click your avatar (top left)
|
|
51
|
+
- Select "Preferences"
|
|
52
|
+
- Click "Access Tokens" in the left sidebar
|
|
53
|
+
- Or go directly to: https://gitlab.com/-/user_settings/personal_access_tokens
|
|
54
|
+
|
|
55
|
+
3. **Create a new token**
|
|
56
|
+
- **Token name**: `mcp-gitlab-crunchtools`
|
|
57
|
+
- **Expiration date**: Set an appropriate expiry (recommended: 90 days)
|
|
58
|
+
- **Scopes**: Select the scopes you need (see below)
|
|
59
|
+
|
|
60
|
+
4. **Copy Your Token**
|
|
61
|
+
- **IMPORTANT: Copy the token immediately!**
|
|
62
|
+
- The token starts with `glpat-` and is only shown once
|
|
63
|
+
- Store it securely (password manager recommended)
|
|
64
|
+
|
|
65
|
+
### Scope Selection
|
|
66
|
+
|
|
67
|
+
#### Read-Only (safest)
|
|
68
|
+
- `read_api` — Read access to projects, issues, MRs, pipelines
|
|
69
|
+
|
|
70
|
+
#### Full Management (all MCP server features)
|
|
71
|
+
- `api` — Full API access for creating/updating issues, MRs, and notes
|
|
72
|
+
|
|
73
|
+
### Security Best Practices
|
|
74
|
+
|
|
75
|
+
- **Principle of least privilege**: Use `read_api` if you only need to read
|
|
76
|
+
- **Set expiration**: Always set an expiry date on tokens
|
|
77
|
+
- **Rotate regularly**: Create new tokens periodically and revoke old ones
|
|
78
|
+
- **Never commit tokens**: Don't put tokens in code or config files in git
|
|
79
|
+
|
|
80
|
+
## Environment Variables
|
|
81
|
+
|
|
82
|
+
| Variable | Required | Default | Description |
|
|
83
|
+
|----------|----------|---------|-------------|
|
|
84
|
+
| `GITLAB_TOKEN` | Yes | — | Personal Access Token (starts with `glpat-`) |
|
|
85
|
+
| `GITLAB_URL` | No | `https://gitlab.com` | GitLab instance URL |
|
|
86
|
+
|
|
87
|
+
## Available Tools (27 tools)
|
|
88
|
+
|
|
89
|
+
### Project Management (5 tools)
|
|
90
|
+
- `list_projects` - List projects with filtering and search
|
|
91
|
+
- `get_project` - Get project details by ID or path
|
|
92
|
+
- `list_project_branches` - List repository branches
|
|
93
|
+
- `get_project_branch` - Get a single branch
|
|
94
|
+
- `list_project_commits` - List commits with date/path filtering
|
|
95
|
+
|
|
96
|
+
### Group Management (3 tools)
|
|
97
|
+
- `list_groups` - List groups with filtering
|
|
98
|
+
- `get_group` - Get group details by ID or path
|
|
99
|
+
- `list_group_projects` - List projects in a group (with subgroup support)
|
|
100
|
+
|
|
101
|
+
### Merge Requests (7 tools)
|
|
102
|
+
- `list_merge_requests` - List MRs by state, labels, milestone
|
|
103
|
+
- `get_merge_request` - Get MR details
|
|
104
|
+
- `create_merge_request` - Create a new MR
|
|
105
|
+
- `update_merge_request` - Update MR title, description, state, assignees
|
|
106
|
+
- `list_mr_notes` - List comments on an MR
|
|
107
|
+
- `create_mr_note` - Add a comment to an MR
|
|
108
|
+
- `get_mr_changes` - Get the diff for an MR
|
|
109
|
+
|
|
110
|
+
### Issues (6 tools)
|
|
111
|
+
- `list_issues` - List issues by state, labels, milestone, assignee
|
|
112
|
+
- `get_issue` - Get issue details
|
|
113
|
+
- `create_issue` - Create a new issue
|
|
114
|
+
- `update_issue` - Update issue title, description, state, labels
|
|
115
|
+
- `list_issue_notes` - List comments on an issue
|
|
116
|
+
- `create_issue_note` - Add a comment to an issue
|
|
117
|
+
|
|
118
|
+
### Pipelines (4 tools)
|
|
119
|
+
- `list_pipelines` - List CI/CD pipelines with status filtering
|
|
120
|
+
- `get_pipeline` - Get pipeline details
|
|
121
|
+
- `list_pipeline_jobs` - List jobs in a pipeline
|
|
122
|
+
- `get_job_log` - Get job log output
|
|
123
|
+
|
|
124
|
+
### Search (2 tools)
|
|
125
|
+
- `search_global` - Search across all accessible GitLab resources
|
|
126
|
+
- `search_project` - Search within a specific project
|
|
127
|
+
|
|
128
|
+
## Example Usage
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
User: List my GitLab projects
|
|
132
|
+
User: Show open merge requests for group/project
|
|
133
|
+
User: Create an issue in my-org/backend titled "Fix login timeout"
|
|
134
|
+
User: Get the diff for MR !42 in my-org/frontend
|
|
135
|
+
User: Show failed pipelines for my-org/api
|
|
136
|
+
User: Search for "authentication" in project my-org/backend
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Development
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
# Install dependencies
|
|
143
|
+
uv sync --all-extras
|
|
144
|
+
|
|
145
|
+
# Run tests
|
|
146
|
+
uv run pytest
|
|
147
|
+
|
|
148
|
+
# Lint
|
|
149
|
+
uv run ruff check src tests
|
|
150
|
+
|
|
151
|
+
# Type check
|
|
152
|
+
uv run mypy src
|
|
153
|
+
```
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# MCP GitLab CrunchTools Container
|
|
2
|
+
# Built on Hummingbird Python image (Red Hat UBI-based) for enterprise security
|
|
3
|
+
#
|
|
4
|
+
# Build:
|
|
5
|
+
# podman build -t quay.io/crunchtools/mcp-gitlab .
|
|
6
|
+
#
|
|
7
|
+
# Run:
|
|
8
|
+
# podman run -e GITLAB_TOKEN=your_token quay.io/crunchtools/mcp-gitlab
|
|
9
|
+
#
|
|
10
|
+
# With Claude Code:
|
|
11
|
+
# claude mcp add mcp-gitlab-crunchtools \
|
|
12
|
+
# --env GITLAB_TOKEN=your_token \
|
|
13
|
+
# -- podman run -i --rm -e GITLAB_TOKEN quay.io/crunchtools/mcp-gitlab
|
|
14
|
+
|
|
15
|
+
# Use Hummingbird Python image (Red Hat UBI-based with Python pre-installed)
|
|
16
|
+
FROM quay.io/hummingbird/python:latest
|
|
17
|
+
|
|
18
|
+
# Labels for container metadata
|
|
19
|
+
LABEL name="mcp-gitlab-crunchtools" \
|
|
20
|
+
version="0.1.0" \
|
|
21
|
+
summary="Secure MCP server for GitLab projects, merge requests, issues, and pipelines" \
|
|
22
|
+
description="A security-focused MCP server for GitLab built on Red Hat UBI" \
|
|
23
|
+
maintainer="crunchtools.com" \
|
|
24
|
+
url="https://github.com/crunchtools/mcp-gitlab" \
|
|
25
|
+
io.k8s.display-name="MCP GitLab CrunchTools" \
|
|
26
|
+
io.openshift.tags="mcp,gitlab,devops"
|
|
27
|
+
|
|
28
|
+
# Set working directory
|
|
29
|
+
WORKDIR /app
|
|
30
|
+
|
|
31
|
+
# Copy project files
|
|
32
|
+
COPY pyproject.toml README.md ./
|
|
33
|
+
COPY src/ ./src/
|
|
34
|
+
|
|
35
|
+
# Install the package and dependencies
|
|
36
|
+
RUN pip install --no-cache-dir .
|
|
37
|
+
|
|
38
|
+
# Verify installation
|
|
39
|
+
RUN python -c "from mcp_gitlab_crunchtools import main; print('Installation verified')"
|
|
40
|
+
|
|
41
|
+
# Default: stdio transport (use -i with podman run)
|
|
42
|
+
# HTTP: --transport streamable-http (use -d -p 8015:8015 with podman run)
|
|
43
|
+
EXPOSE 8015
|
|
44
|
+
ENTRYPOINT ["python", "-m", "mcp_gitlab_crunchtools"]
|