GitLab CI Integration
This guide shows you how to integrate MCP Security Score into your GitLab CI/CD pipelines using the API.
Prerequisites
- Pro subscription with API access
- API key from Dashboard → Settings
Setup
Step 1: Add Your API Key as a Variable
- Go to your GitLab project
- Navigate to Settings → CI/CD → Variables
- Click Add variable
- Key:
MCP_SCANNER_API_KEY - Value: Your API key (mcp_sk_...)
- Check Mask variable to hide in logs
- Click Add variable
Step 2: Create the Pipeline
Create .gitlab-ci.yml in your repository:
stages:
- security
mcp-security-scan:
stage: security
image: alpine:latest
variables:
SCORE_THRESHOLD: "70"
before_script:
- apk add --no-cache curl jq
script:
- |
set -e
REPO_URL="${CI_PROJECT_URL}"
echo "Scanning $REPO_URL..."
# Create scan
SCAN_RESPONSE=$(curl -sf -X POST "https://mcpscanner.com/api/v1/scan" \
-H "Authorization: Bearer $MCP_SCANNER_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"url\": \"$REPO_URL\"}")
SCAN_ID=$(echo "$SCAN_RESPONSE" | jq -r '.id')
echo "Scan ID: $SCAN_ID"
# Poll for completion
for i in $(seq 1 24); do
RESULT=$(curl -sf "https://mcpscanner.com/api/v1/scan/$SCAN_ID" \
-H "Authorization: Bearer $MCP_SCANNER_API_KEY")
STATUS=$(echo "$RESULT" | jq -r '.status')
echo "Status: $STATUS"
if [ "$STATUS" = "complete" ]; then
break
elif [ "$STATUS" = "failed" ]; then
echo "Scan failed!"
exit 1
fi
sleep 5
done
# Check results
SCORE=$(echo "$RESULT" | jq -r '.score')
GRADE=$(echo "$RESULT" | jq -r '.grade')
FINDINGS=$(echo "$RESULT" | jq -r '.findings | length')
echo ""
echo "=== Results ==="
echo "Score: $SCORE ($GRADE)"
echo "Findings: $FINDINGS"
if [ "$SCORE" -lt "$SCORE_THRESHOLD" ]; then
echo "❌ Score $SCORE is below threshold $SCORE_THRESHOLD"
exit 1
else
echo "✅ Security check passed"
fi
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCHComplete Example with Artifacts
This version saves results as an artifact:
stages:
- security
mcp-security-scan:
stage: security
image: alpine:latest
variables:
SCORE_THRESHOLD: "70"
before_script:
- apk add --no-cache curl jq
script:
- |
set -e
REPO_URL="${CI_PROJECT_URL}"
# Create scan
SCAN_RESPONSE=$(curl -sf -X POST "https://mcpscanner.com/api/v1/scan" \
-H "Authorization: Bearer $MCP_SCANNER_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"url\": \"$REPO_URL\"}")
SCAN_ID=$(echo "$SCAN_RESPONSE" | jq -r '.id')
# Poll for completion
for i in $(seq 1 24); do
RESULT=$(curl -sf "https://mcpscanner.com/api/v1/scan/$SCAN_ID" \
-H "Authorization: Bearer $MCP_SCANNER_API_KEY")
STATUS=$(echo "$RESULT" | jq -r '.status')
if [ "$STATUS" = "complete" ] || [ "$STATUS" = "failed" ]; then
break
fi
sleep 5
done
# Save full results
echo "$RESULT" | jq '.' > security-report.json
# Extract key metrics
SCORE=$(echo "$RESULT" | jq -r '.score')
GRADE=$(echo "$RESULT" | jq -r '.grade')
FINDINGS=$(echo "$RESULT" | jq -r '.findings | length')
CRITICAL=$(echo "$RESULT" | jq '[.findings[] | select(.severity == "critical")] | length')
HIGH=$(echo "$RESULT" | jq '[.findings[] | select(.severity == "high")] | length')
# Create summary
cat > security-summary.txt << EOF
MCP Security Score Security Report
===========================
Repository: $REPO_URL
Scan ID: $SCAN_ID
Score: $SCORE ($GRADE)
Total Findings: $FINDINGS
- Critical: $CRITICAL
- High: $HIGH
Full report: https://mcpscanner.com/dashboard/scan/$SCAN_ID
EOF
cat security-summary.txt
# Fail if below threshold
if [ "$SCORE" -lt "$SCORE_THRESHOLD" ]; then
exit 1
fi
artifacts:
paths:
- security-report.json
- security-summary.txt
expire_in: 30 days
when: always
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCHMerge Request Only
Scan only on merge requests to save API calls:
mcp-security-scan:
stage: security
# ... same configuration ...
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"Scheduled Scans
Run security scans on a schedule:
mcp-security-scan:
stage: security
# ... same configuration ...
rules:
- if: $CI_PIPELINE_SOURCE == "schedule"
- if: $CI_PIPELINE_SOURCE == "web" # Manual triggerThen create a schedule in CI/CD → Schedules.
Using Docker Image
For faster builds, use an image with curl and jq pre-installed:
mcp-security-scan:
stage: security
image: curlimages/curl:latest
before_script:
- apk add --no-cache jq
# ... rest of configuration ...Troubleshooting
"Unauthorized" Error
Check that:
- Variable name is exactly
MCP_SCANNER_API_KEY - Variable is not protected (or branch is protected)
- API key is valid and not expired
Scan Times Out
Increase the poll iterations:
# Poll for longer (60 iterations × 5 seconds = 5 minutes)
for i in $(seq 1 60); doVariable Not Available
If the variable is protected, it won't be available on unprotected branches. Either:
- Uncheck "Protected" on the variable
- Or run scans only on protected branches
Next Steps
- Other CI Systems - Jenkins, CircleCI
- Rate Limits - Handling limits
- API Examples - Code samples