Building a Fully Automated SonarCloud Pipeline Using Claude's MCP
Source: Dev.to
Introduction
I wanted SonarCloud code‑quality reports without constantly switching between my terminal, GitHub, and SonarCloud’s web UI.
Goal: Type one command in Claude Code and get a full quality report back—instantly.
Turns out Claude Code’s MCP (Model Context Protocol) ecosystem makes this possible — but getting there involved:
- 9 distinct failures
- 3 PAT permission updates
- 1 important discovery about how GitHub reports CI status
What I Built
A fully automated pipeline:
You write code
→ Claude commits & pushes
→ Creates PR via GitHub MCP
→ GitHub Actions runs sonar‑scanner
→ Claude polls for completion
→ Pulls report via SonarQube MCP
→ Shows quality gate + issues table
| Metric | Value |
|---|---|
| Total time (commit → report) | ~2.5 minutes |
| Manual steps (after one‑time setup) | 0 |
The Stack
| Component | Role |
|---|---|
| Claude Code CLI | Orchestrator |
| mcp/sonarqube | Reads SonarCloud data — quality gates, issues, metrics |
| ghcr.io/github/github‑mcp‑server | Manages repos, branches, PRs |
| GitHub Actions | Runs the sonar‑scanner |
| SonarCloud (free tier) | Hosts analysis results |
Setup: The Happy Path (~30 min)
SonarCloud
- Import your project via “Analyze new project” (don’t create manually).
- Disable Automatic Analysis.
- Generate a Project Analysis Token (not a user token – see Challenge #3).
GitHub PAT (Fine‑grained)
| Permission | Level | Why |
|---|---|---|
| Contents | Read & Write | Push files |
| Workflows | Read & Write | Create .github/workflows/ files |
| Actions | Read & Write | Manage workflow runs |
| Pull requests | Read & Write | Create PRs |
| Commit statuses | Read | Poll CI status |
| Metadata | Read | Required |
Missing any one of these causes 403 errors at different stages.
Workflows and Commit statuses are the most commonly missed.
MCP Servers
# Pull Docker images
docker pull mcp/sonarqube
docker pull ghcr.io/github/github-mcp-server
# Add to Claude Code (run from terminal, NOT inside Claude)
claude mcp add sonarqube \
--env SONARQUBE_TOKEN=YOUR_TOKEN \
--env SONARQUBE_ORG=YOUR_ORG \
-- docker run -i --rm -e SONARQUBE_TOKEN -e SONARQUBE_ORG mcp/sonarqube
claude mcp add github \
-e GITHUB_PERSONAL_ACCESS_TOKEN=YOUR_PAT \
-- docker run -i --rm -e GITHUB_PERSONAL_ACCESS_TOKEN \
ghcr.io/github/github-mcp-server
# RESTART Claude Code (MCP servers only load on startup)
GitHub Actions Workflow
Add two files to your repo:
sonar-project.properties
sonar.projectKey=YourOrg_yourrepo
sonar.organization=yourorg
sonar.sources=src
sonar.exclusions=**/node_modules/**,**/dist/**
.github/workflows/sonarcloud.yml
name: SonarCloud Analysis
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
sonarcloud:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: SonarSource/sonarqube-scan-action@v5
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
Claude can create both files via the GitHub MCP — no manual file creation needed.
The only browser step: add SONAR_TOKEN as a GitHub Actions secret.
The 9 Challenges (In Order)
| # | Issue | Fix |
|---|---|---|
| 1 | MCP Server Not Connecting – added server via claude mcp add but tools weren’t available. | Restart Claude Code (servers load only on startup). |
| 2 | Docker Image Not Pulled – config was correct but server wouldn’t start. | Run docker pull mcp/sonarqube first. |
| 3 | “Project Not Found” – scanner ran but couldn’t locate the project. | Use a Project Analysis Token (SonarCloud → My Account → Security). |
| 4 | 403 on Workflow File – Claude couldn’t create .github/workflows/sonarcloud.yml. | Add Workflows: Read & Write to the PAT. |
| 5 | Invalid sonar.sources – source directories didn’t exist on the scanned branch. | Ensure sonar.sources points to directories that exist on that branch. |
| 6 | Automatic Analysis Conflict – “You are running CI analysis while Automatic Analysis is enabled.” | Disable Automatic Analysis in SonarCloud UI (cannot be done via MCP). |
| 7 | Branch Analysis 404 – quality gate returned 404 for non‑default branches. | Free tier supports only main + PR analysis. Use PR‑based analysis. |
| 8 | Go Not Supported by Automatic Analysis – only JS/TS, Python, Java, C# are supported. | Use the GitHub Actions CI approach for compiled languages. |
| 9 | PR Creation 403 – PAT missing Pull‑request permission. | Add Pull requests: Read & Write to the PAT. |
The Interesting Discovery: GitHub Status vs. Check Runs
During polling I used pull_request_read(get_status) to see if CI was done, but it kept returning “pending” even after SonarCloud finished.
Why? SonarCloud reports results via GitHub Check Runs, not Commit Statuses. The get_status method checks commit statuses, so it never sees the completed check run.
Fix: Use the SonarQube MCP as the primary polling method:
get_project_quality_gate_status(pullRequest: "PR_NUMBER")
When this call returns data (instead of an error), the analysis is complete—far more reliable than the GitHub status API.
Dry‑Run Results
| Step | Time |
|---|---|
| Commit + push | ~5 s |
| Create PR | ~2 s |
| Poll (4 × 30 s) | ~2 min |
| Pull report | ~3 s |
| Total | ~2.5 min |
Quality Gate
❌ FAILED (intentionally)
Issues Found
6 total – 2 Critical, 1 Major, 3 Minor
Eliminating Approval Fatigue
By default Claude Code asks permission for every tool call. For an automated flow this kills the experience.
Solution: Add an auto‑approval block to .claude/settings.local.json:
{
"permissions": {
"allow": [
"Bash(git status:*)",
"Bash(git add:*)",
"Bash(git commit:*)",
"Bash(git push:*)",
"Bash(sleep:*)",
"mcp__sonarqube__get_project_quality_gate_status",
"mcp__sonarqube__search_sonar_issues_in_projects",
"mcp__github__create_pull_request",
"mcp__github__pull_request_read"
]
}
}
This auto‑approves the necessary Git commands, polling sleeps, and MCP tool calls, giving you a truly one‑command experience.
What MCP Can and Can’t Do
✅ Can do
- Read quality gates, issues, metrics
- Trigger GitHub Actions re‑runs
- Create files, branches, PRs
- Create GitHub secrets
- Push commits, read diffs
- Change SonarCloud project settings
- Analyze code snippets locally
- Monitor workflow logs in real‑time
❌ Can’t do (yet)
(no items listed)
Free Tier Tips
- Private repos: 50 k lines free. Use
sonar.exclusionsaggressively. - PR analysis: Works on the free tier and only scans new code — the best strategy for staying under limits.
- Branch analysis: Requires a paid tier. Use PRs instead.
The Full Guide
Everything above plus example configs, the “Feed to Claude” instructions (so any Claude Code instance can run the flow), and detailed troubleshooting:
aadhin/claude-sonarcloud‑guide on GitHub
Built while working on a Go + React/TypeScript desktop app (Wails v2). SonarCloud free tier + GitHub Actions CI.