sonarqube-mcp
๐ PyPI
๐ Python
๐ License: MIT
SonarQube์ฉ MCP ์๋ฒ์ ๋๋ค. LLM ์์ด์ ํธ(Claude Code, Cursor, OpenCode ๋ฑ)๊ฐ ํ๋ก์ ํธ๋ฅผ ๊ฒ์ํ๊ณ , ์ฃผ์ ์งํ๋ฅผ ๊ฐ์ ธ์ค๊ณ , ํ์ง ๊ฒ์ดํธ ์ํ๋ฅผ ํ์ธํ๊ณ , ์ฌ๊ฐ๋/์ ํ ํํฐ๋ก ์ด์๋ฅผ ๊ฒ์ํ๋ฉฐ, ์งํ๊ฐ ๊ฐ์ฅ ๋์ ํ๋ก์ ํธ ์์๋ฅผ ๋งค๊ธธ ์ ์๊ฒ ํฉ๋๋ค.
Python, FastMCP, stdio ์ ์ก์ ์ฌ์ฉํฉ๋๋ค.
๋ชจ๋ SonarQube 9.x / 10.x ์ธ์คํด์ค(์์ฒด ํธ์คํ ) ๋ฐ SonarCloud์ ํธํ๋ฉ๋๋ค.
์ ๋ ๋ค๋ฅธ SonarQube MCP์ธ๊ฐ์?
๊ธฐ์กด์๋ ๋ช ๊ฐ์ง SonarQube MCP๊ฐ ์กด์ฌํ์ง๋ง, ๋๋ถ๋ถ ๋จ์ผ ํ๋ก์ ํธ ์ฝ๊ธฐ ์์ค์์ ๋ฉ์ถฐ ์์ต๋๋ค. ์ด ์๋ฒ๋ ํ๋ก์ ํธ ๊ฐ ์์ ๋งค๊ธฐ๊ธฐ(sonarqube_worst_metrics) ๊ธฐ๋ฅ์ ์ถ๊ฐํ์ต๋๋ค. ์ด๋ ๋ฆฌ๋ ๊ฐ๋ฐ์๊ฐ ํธ๋ฆฌ์์ง ์ธ์
์ค์ ์ค์ ๋ก ์ํํ๋ ์์
์ธ "์กฐ์ง ๋ด์์ ์ปค๋ฒ๋ฆฌ์ง๊ฐ ๊ฐ์ฅ ๋ฎ์ ์์ 10๊ฐ ์๋น์ค ๋ณด์ฌ์ค"์ ๊ฐ์ ์์ฒญ์ ์ฒ๋ฆฌํฉ๋๋ค. ๋ชจ๋ ๋๊ตฌ๋ ์ฝ๊ธฐ ์ ์ฉ์ด๋ฉฐ ์์ ํ๊ฒ ๋งค๊ฐ๋ณ์ํ๋์ด ์์ต๋๋ค(Pydantic ์
๋ ฅ ์ ํจ์ฑ ๊ฒ์ฌ, ์ฌ๊ฐ๋/์ ํ ํ์ดํธ๋ฆฌ์คํธ).
Related MCP server: sonarqube-api-mcp
์ค๊ณ ํน์ง
๋๊ตฌ ์ฃผ์ โ 5๊ฐ์ง ๋๊ตฌ ๋ชจ๋
readOnlyHint: True,destructiveHint: False,idempotentHint: True๋ฅผ ํฌํจํฉ๋๋ค. ์ด ์๋ฒ๋ฅผ ํตํด SonarQube์ ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.๊ตฌ์กฐํ๋ ์ถ๋ ฅ โ ๋ชจ๋ ๋๊ตฌ๋ ํ์ ์ด ์ง์ ๋ ํ์ด๋ก๋(TypedDict)์ ๋งํฌ๋ค์ด ์์ฝ์ ๋ฐํํ๋ฏ๋ก, ๊ตฌ์กฐํ๋ ์ฝํ ์ธ ์ง์ ์ฌ๋ถ์ ๊ด๊ณ์์ด ํด๋ผ์ด์ธํธ๊ฐ ์๋ต์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๊ตฌ์กฐํ๋ ์ค๋ฅ โ 401 / 403 / 404 / 400 / 429 / 5xx ์ค๋ฅ๊ฐ ์คํ ๊ฐ๋ฅํ ํํธ(์: "ํ ํฐ ์ฌ์์ฑ", "sonarqube_list_projects๋ก ํ๋ก์ ํธ ํค ํ์ธ")์ ํจ๊ป ๋งคํ๋ฉ๋๋ค.
Pydantic ์ ๋ ฅ ์ ํจ์ฑ ๊ฒ์ฌ โ ๋ชจ๋ ์ธ์์ ๋ํด ์ ์ฉ๋๋ฉฐ, ์์ฒญ์ด ์ ์ก๋๊ธฐ ์ ์ ์ฌ๊ฐ๋/์ ํ ํํฐ๊ฐ ์ ํจํ SonarQube ์ด๊ฑฐํ๊ณผ ๋์กฐ๋์ด ํ์ธ๋ฉ๋๋ค.
ํ๋ก์ ํธ ๊ฐ ์ต์ ์งํ ์์ ๋งค๊ธฐ๊ธฐ โ ๋ด๋ถ์ ์ผ๋ก
/api/measures/searchํธ์ถ์ ์ผ๊ด ์ฒ๋ฆฌํ๋ฉฐ, ์ ํํ ์งํ์ ๋ฐ๋ผ ๊ฐ์ด ๋์์๋ก ๋์์ง ๋ฎ์์๋ก ๋์์ง์ ๋ง์ถฐ ์ค๋ฆ์ฐจ์ ๋๋ ๋ด๋ฆผ์ฐจ์์ผ๋ก ์ ๋ ฌํฉ๋๋ค.
๊ธฐ๋ฅ (5๊ฐ์ง ๋๊ตฌ)
๊ฒ์
sonarqube_list_projectsโ ์ ํ์ ํ ์คํธ ํํฐ๋ฅผ ํฌํจํ ํ์ด์ง๋ค์ด์ ํ๋ก์ ํธ ๊ฒ์
๋จ์ผ ํ๋ก์ ํธ ํต์ฐฐ
sonarqube_project_metricsโ ๋จ์ผ ํ๋ก์ ํธ์ ๋ํ ์ธก์ ๊ฐ(๊ธฐ๋ณธ ์ธํธ: ๋ฒ๊ทธ / ์ปค๋ฒ๋ฆฌ์ง / ์ฝ๋ ์ค๋ฉ / ๋ฑ๊ธ / ncloc / ํ ์คํธ / alert_status)sonarqube_quality_gate_statusโ ํ์ง ๊ฒ์ดํธ ์ํ + ์กฐ๊ฑด๋ณ ์คํจ ๋ด์ญ
์ด์ ํธ๋ฆฌ์์ง
sonarqube_get_issuesโ ์ฌ๊ฐ๋ / ์ ํ / ํด๊ฒฐ ์ํ๋ณ๋ก ํํฐ๋ง๋ ์ด์ ๊ฒ์
ํ๋ก์ ํธ ๊ฐ ์์ ๋งค๊ธฐ๊ธฐ
sonarqube_worst_metricsโ ์งํ์ ์ต์ ๊ฐ(์: ์ต์ ์ ์ปค๋ฒ๋ฆฌ์ง, ๊ฐ์ฅ ๋ง์ ๋ฒ๊ทธ)์ ๊ธฐ์ค์ผ๋ก ์์ N๊ฐ ํ๋ก์ ํธ ์ ๋ ฌ
์ค์น
Python 3.10+๊ฐ ํ์ํฉ๋๋ค.
# via uvx (recommended โ no install, just run)
uvx --from sonarqube-mcp sonarqube-mcp
# or via pipx
pipx install sonarqube-mcp๊ตฌ์ฑ
claude mcp add sonarqube -s project \
--env SONARQUBE_URL=https://sonar.example.com \
--env SONARQUBE_TOKEN=squ_your_token \
--env SONARQUBE_SSL_VERIFY=true \
-- uvx --from sonarqube-mcp sonarqube-mcp๋๋ .mcp.json ํ์ผ:
{
"mcpServers": {
"sonarqube": {
"type": "stdio",
"command": "uvx",
"args": ["--from", "sonarqube-mcp", "sonarqube-mcp"],
"env": {
"SONARQUBE_URL": "https://sonar.example.com",
"SONARQUBE_TOKEN": "${SONARQUBE_TOKEN}",
"SONARQUBE_SSL_VERIFY": "true"
}
}
}
}ํ์ธ:
claude mcp list
# sonarqube: uvx --from sonarqube-mcp sonarqube-mcp - โ Connectedํ๊ฒฝ ๋ณ์
๋ณ์ | ํ์ | ์ค๋ช |
| ์ | SonarQube URL (๋์ ์ฌ๋์ ์ ์ธ) |
| ์ | Bearer ํ ํฐ. ์์ฑ ์์น: ๋ด ๊ณ์ โ ๋ณด์ โ ํ ํฐ |
| ์๋์ค |
|
HTTP ํ๋ก์ ๊ด๋ จ ์ฐธ๊ณ ์ฌํญ. ์์ฒด ํธ์คํ
๋ SonarQube๋ ์ผ๋ฐ์ ์ผ๋ก ๋ด๋ถ ๋คํธ์ํฌ์์๋ง ์ ๊ทผ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์, ํด๋ผ์ด์ธํธ๋ ์๋์ ์ผ๋ก ํ๊ฒฝ ๊ธฐ๋ฐ ํ๋ก์ ๊ฒ์(trust_env=False)์ ๋นํ์ฑํํฉ๋๋ค. SonarCloud๋ ๊ธฐ์
ํ๋ก์ ๋ค์ ์๋ SonarQube์ ์ฐ๊ฒฐํ๋ ๊ฒฝ์ฐ, ํ์ฌ๋ ํ๋ก์ธ์ค ์์ค์์ ํ๋ก์ ๋ณ์๋ฅผ ์ ๊ฑฐํด์ผ ํฉ๋๋ค. ํฅํ ๋ฆด๋ฆฌ์ค์์ SONARQUBE_TRUST_ENV_PROXY ์ต์
์ด ์ถ๊ฐ๋ ์์ ์
๋๋ค.
์ฌ์ฉ ์์
"'einvy'์ ์ผ์นํ๋ ๋ชจ๋ SonarQube ํ๋ก์ ํธ ๋์ด"
"
einvy:aut_einvy์ ํ์ง ๊ฒ์ดํธ ์ํ๋ ๋ฌด์์ธ๊ฐ์?""๋ฒ๊ทธ๊ฐ ๊ฐ์ฅ ๋ง์ ์์ 10๊ฐ ํ๋ก์ ํธ๋ฅผ ๋ณด์ฌ์ค"
"
einvy:aut_einvy์์ ๋ชจ๋ BLOCKER / CRITICAL ์ทจ์ฝ์ ์ฐพ๊ธฐ""
einvy:qa_assistant์ ์ปค๋ฒ๋ฆฌ์ง๋ ์ผ๋ง์ธ๊ฐ์?""'einvy' ์ฟผ๋ฆฌ์ ์ผ์นํ๋ ์ปค๋ฒ๋ฆฌ์ง๊ฐ ๊ฐ์ฅ ๋ฎ์ ์์ 5๊ฐ ํ๋ก์ ํธ"
์งํ ๋ฐฉํฅ (sonarqube_worst_metrics์์ ์ฌ์ฉ)
๋์์๋ก ๋์จ (๋ด๋ฆผ์ฐจ์ ์ ๋ ฌ โ ๋ง์์๋ก ๋์จ):
bugs, code_smells, vulnerabilities, duplicated_lines_density, reliability_rating, security_rating, security_review_rating, sqale_rating, open_issues
๋ฎ์์๋ก ๋์จ (์ค๋ฆ์ฐจ์ ์ ๋ ฌ โ ์ ์์๋ก ๋์จ):
coverage, line_coverage, branch_coverage, test_success_density, tests
SonarQube์ ๋ฑ๊ธ์ ์ซ์ ๋ฌธ์์ด๋ก ํ์๋๋ฉฐ, "1"(A, ์ต๊ณ )๋ถํฐ "5"(E, ์ต์
)๊น์ง์
๋๋ค.
์์ ์ฑ
๋ชจ๋ ๋๊ตฌ๋
readOnlyHint: True๋ก ์ค์ ๋์ด ์์ด SonarQube ๋ฐ์ดํฐ๋ฅผ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.POST/PUT/DELETE์์ฒญ์ ์ ๋ ํธ์ถ๋์ง ์์ต๋๋ค.์ฌ๊ฐ๋ / ์ ํ / ํ์ ์ ์ ๋ ฅ์ API ํธ์ถ ์ ์ SonarQube ์ด๊ฑฐํ๊ณผ ๋์กฐํ์ฌ ๊ฒ์ฆ๋๋ฏ๋ก, ์คํ๊ฐ ์์ ๊ฒฝ์ฐ API๋ฅผ ํธ์ถํ๊ธฐ ์ ์ ๋๊ตฌ๊ฐ ์ฆ์ ์คํจํฉ๋๋ค.
์ฑ๋ฅ ํน์ฑ
sonarqube_worst_metrics๋ฅผ ์ ์ธํ ๋ชจ๋ ๋๊ตฌ๋ SonarQube์ ํ๋์ HTTP ํธ์ถ์ ์ํํฉ๋๋ค.sonarqube_worst_metrics๋ ํ๋์ ๊ฒ์ ํธ์ถ + โํ๋ณด๊ตฐ/100โ๋ฒ์ ๋๋ ์ธก์ ๊ฐ ํธ์ถ์ ์ํํฉ๋๋ค. ๊ธฐ๋ณธ ์ค์ ์ ํธ์ถ ํ์๋ 2ํ ์ดํ์ ๋๋ค.์ ์์ ์ธ SonarQube ์ธ์คํด์ค์์์ ๋จ์ผ ๋๊ตฌ ์๋ต ์๊ฐ: ์ผ๋ฐ์ ์ผ๋ก 500ms ๋ฏธ๋ง.
ํ์ด์ง๋ค์ด์ ์ SonarQube๋ก ์ ๋ฌ(
p+ps๋งค๊ฐ๋ณ์)๋๋ฏ๋ก MCP ์๋ฒ์์ ์ ์ฒด ๊ฒฐ๊ณผ๋ฅผ ๋ฒํผ๋งํ์ง ์์ต๋๋ค.sonarqube_worst_metrics๋candidate_pool์ 500์ผ๋ก ์ ํํฉ๋๋ค. ์์ฒ ๊ฐ์ ํ๋ก์ ํธ๊ฐ ์๋ ์ธ์คํด์ค์์๋ ์์๋ฅผ ๋งค๊ธฐ๊ธฐ ์ ์query=๋ก ๋ฏธ๋ฆฌ ํํฐ๋งํ์ญ์์ค(๋๊ตฌ ๋ ์คํธ๋ง ์ฐธ์กฐ).SonarQube์๋ ๊ณต๊ฐ๋ ์๊ฒฉํ ์๋ ์ ํ์ด ์์ต๋๋ค. 429 ์ค๋ฅ๊ฐ ์์ ๋๋ฉด ์๋ฒ๋ ์คํ ๊ฐ๋ฅํ ์ค๋ฅ ๋ฉ์์ง("์ฌ์๋ ์ 30-60์ด ๋๊ธฐ; page_size ์ถ์")๋ฅผ ํ์ํฉ๋๋ค.
๊ฐ๋ฐ
git clone https://github.com/mshegolev/sonarqube-mcp.git
cd sonarqube-mcp
pip install -e '.[dev]'
pytest๋ผ์ด์ ์ค
MIT ยฉ Mikhail Shchegolev
Maintenance
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/mshegolev/sonarqube-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
