AI 품질 게이트
AI 코드 품질 자동화를 위한 MCP 서버입니다.
npm version
License: MIT
기능 설명 (What It Does)
AI가 코드를 작성하면 → quality_fix를 호출하고 → 서버가 수정 가능한 부분을 고치며 → 남아있는 이슈를 AI에게 보고합니다.
하이브리드 접근 방식:
- 단계 1 (Phase 1): ESLint + 627 규칙 + Prettier (~2-8초, 항상 실행)
- 단계 2 (Phase 2): SonarQube Server (~30-60초, 선택 사항)
중요: ESLint 대 Prettier
| 도구 | 소스 | 설정 |
|---|
| ESLint | 프로젝트의 설정 (존재하는 경우) 또는 MCP 내장 기능 | .eslintrc.* / eslint.config.* / MCP 내장 기능 |
| Prettier | 프로젝트 자체 | 프로젝트의 prettier.config.mjs |
ESLint 규칙은 일관된 품질 게이트를 위해 MCP에 의해 제어됩니다.
Prettier는 프로젝트 설정을 사용하므로 포맷팅이 프로젝트 선호도와 일치합니다.
단계 1 규칙 범위:
| 플러그인 | 규칙 수 | 설명 |
|---|
| SonarJS | 201 | 보안, 버그, 코드 스멜 (code smells) |
| ... | | |
설치 (Installation)
전제 조건 (Prerequisites)
- PATH에 **Node.js 20.10+ 또는 21.1+**가 설치되어 있어야 합니다 (
node -v).
- MCP를 활성화한 Cursor, Antigravity, OpenCode (또는 다른 MCP 지원 에디터)가 필요합니다.
PROJECT_ROOT를 생략하면 프로젝트 루트 경로는 자동 감지됩니다. 서버는 MCP 프로세스가 실행되는 디렉토리에서 package.json 또는 tsconfig.json을 찾을 때까지 상위로 올라갑니다. 추론된 루트와 다른 트리를 분석하려면 환경 변수 env에 PROJECT_ROOT를 설정하세요.
MCP 설정 (Cursor)
설정(Settings) → 도구 및 MCP(Tools & MCP) → 편집(Edit)을 열어 사용자 mcp.json 파일을 수정합니다. 서버 블록을 하나 추가해야 합니다. 아래 예시는 .cursor/mcp.json.example과 일치하며 (주석이 포함된 JSONC 형식 — 에디터가 주석을 거부하는 경우, 아래의 JSON 블록만 복사하세요).
서버 이름 vs 도구 이름: mcpServers 아래의 키(예: "ai-quality-gate")는 Cursor에서 해당 연결에 대한 레이블일 뿐입니다. 에이전트가 호출하는 MCP 도구는 항상 quality_fix이며, 이 이름은 패키지에 의해 고정되어 서버 키 및 ai-quality-gate와 분리됩니다.
A) 권장: npx (글로벌 설치 불필요)
항상 게시된 패키지를 실행합니다. 팀 환경이나 CI(지속적 통합)와 같은 설정에 적합합니다.
{
"mcpServers": {
"ai-quality-gate": {
...
B) 선택 사항: 글로벌 npm 설치
npm i -g ai-quality-gate 실행 후, ai-quality-gate 바이너리가 PATH에 추가됩니다:
{
"mcpServers": {
"ai-quality-gate": {
...
C) SonarQube (Phase 2)
실행 중인 SonarQube 인스턴스, 사용 가능한 sonar-scanner (아래 SonarQube 설정 참조), 그리고 아래의 세 가지 변수가 필요합니다. Phase 1이 여전히 먼저 실행됩니다.
{
"mcpServers": {
"ai-quality-gate": {
...
D) 선택적 환경 변수 (모든 서버)
재정의(overrides)가 필요할 때 `
OpenCode 설정을 생성하거나 편집합니다 (OpenCode config) (일반적으로 ~/.config/opencode/opencode.json 또는 프로젝트 레벨 설정):
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
...
필요한 경우 서버 설정 아래에 환경 변수를 추가할 수 있습니다 (위의 C) SonarQube (Phase 2) 참조).
로컬 개발 (이 저장소)
자체 테스트(dogfood)를 하거나 기여하려면:
yarn build — dist/server.js 파일을 생성합니다.
- MCP가 빌드된 파일(절대 경로)을 가리키도록 설정합니다:
{
"mcpServers": {
"ai-quality-gate-dev": {
...
- MCP를 다시 로드합니다. 분석하는 저장소가 추론된 루트와 다른 경우에만
env.PROJECT_ROOT를 사용하세요.
2. AI 규칙 추가
Settings → Rules and Commands → Add Rule:
모든 코드 변경 후, 사용자에게 "완료"라고 알리기 전에,
AI는 quality_fix MCP 도구를 호출해야 합니다. 이는 필수입니다.
3. 사용하기
AI가 코드를 작성 → quality_fix 호출 → 오류 수정 → "완료 ✅"
CLI: 대화형 설정 (--setup)
**대화형 마법사(interactive wizard)**는 수동 편집 없이 .quality-gate.yaml 파일을 생성하거나 업데이트합니다. 이 도구는 프로젝트 루트, 선택적 SonarQube (호스트 URL + 프로젝트 키; 토큰은 디스크에 저장되지 않습니다 — 환경 변수에서 SONAR_TOKEN 사용), 활성화할 Phase 1 도구(ESLint, curly-brace / arrow AST fixers, Prettier, JSON validator), 타임아웃 및 i18n 규칙에 대해 안내합니다. 생성된 파일에는 나중에 조정할 수 있는 fixers: 블록이 포함됩니다.
yarn build를 실행하거나 (또는 npm에서 설치한 후) 대상 프로젝트(또는 그 하위의 모든 경로)에서 다음 명령을 실행합니다:
node dist/server.js --setup
PROJECT_ROOT는 설정되지 않은 경우 추론됩니다 ( MCP 구성 참조). MCP 서버와 동일한 진입점(node dist/server.js 또는 npx ai-quality-gate)을 사용합니다. --setup 플래그만 마법사 모드로 전환합니다. 터미널에서 프롬프트에 응답하면, 성공적으로 완료된 후 프로젝트 루트 옆에 바로 사용할 수 있는 설정 파일을 얻게 됩니다.
다른 CLI 모드: --check (읽기 전용 Phase 1), --fix (CLI 품질 실행 시 기본 동작), --phase1-only, --phase2-only — 자세한 내용은 docs/DEVELOPMENT.md를 참조하십시오.
선택 사항: SonarQube 서버 (Phase 2)
위의 **C) SonarQube (Phase 2)**에서와 같이 MCP에 Sonar 환경을 구성하거나, .cursor/mcp.json.example에서 복사할 수 있습니다. 분석을 위해서는 로컬 머신에 **sonar-scanner**가 필요합니다 (아래 참조).
SonarQube 설정
Docker (권장)
docker run -d --name sonarqube -p 9000:9000 sonarqube:community
...
Docker Compose
version: '3'
services:
...
SonarQube 토큰 생성
- http://localhost:9000 → 로그인 (관리자)
- My Account → Security → Generate Tokens
- 토큰 유형 선택: Global Analysis Token
- 토큰 복사 →
SONAR_TOKEN으로 사용
sonar-scanner 설치
| 플랫폼 | 방법 | 명령어 |
|---|
| Windows | npm (전역) | npm install -g sonarqube-scanner |
| ... | | |
사용자 정의 경로의 경우: SONAR_SCANNER_PATH 환경 변수
구성(Configuration)
선택적 파일 (추론된 프로젝트 루트에서 상위로 탐색하거나 — package.json / tsconfig.json과 동일한 알고리즘 사용 — 또는 PROJECT_ROOT가 설정된 경우)을 통해 발견됩니다: .quality-gate.yaml (권장) 또는 .quality-gate.json. 환경 변수와 동일한 필드(camelCase)를 사용하며, Sonar 설정을 sonar: { hostUrl, token, projectKey, scannerPath } 아래에 중첩할 수 있습니다.
병합 순서: 기본값(defaults) → 설정 파일 → 환경 변수 (충돌 시 ENV가 우선합니다).
명시적인 경로를 지정하여 탐색을 건너뛰려면 **QUALITY_GATE_CONFIG**를 설정하십시오.
사용자 정의 규칙 (customRules)
선택적 라인 기반 정규식(regex) 검사 (Phase 1)를 린팅 가능한 파일에 적용할 수 있습니다. 각 일치 항목은 rule이 custom:<id>로 설정된 이슈로 보고되며 (quality_fix의 remaining에 포함됩니다). 예시:
customRules:
- id: no-console
message: 'Console.log는 허용되지 않습니다'
...
패턴은 JavaScript RegExp 소스를 사용합니다 (YAML 문자열 내에서 백슬래시는 이스케이프 처리해야 합니다). 유효하지 않은 패턴은 건너뛰어지며, 이는 warnings에 명시됩니다.
JSON 검증기 및 i18n 로케일 파일
**fixers.jsonValidator**가 활성화되고 로케일 패턴과 일치하는 JSON 경로(예: locales/en.json / locales/tr.json)를 전달하면, 도구는 해당 파일들 간의 키를 비교합니다.
- 문법 오류, 유효하지 않은 UTF-8 BOM 등 →
issues로 보고되며 수정될 때까지 Phase 1 / quality_fix가 실패합니다.
- 로케일 파일 간 누락되거나 추가된 키 → 검증기 결과의 **
i18nIssues**로 수집되어 Phase 1 동안 **stderr에 경고(warnings)**로 출력됩니다. 이들은 passed: false를 설정하지 않으며 게이트를 차단하지 않습니다.
사용자가 별도의 CI 검사를 추가하지 않는 한, i18nIssues는 참고용으로 간주하십시오.
환경 변수 (Environment Variables)
모든 변수는 선택 사항입니다. Phase 2를 사용할 경우에만 SONAR_HOST_URL, SONAR_TOKEN, 그리고 SONAR_PROJECT_KEY 세 가지가 모두 필요합니다.
| 변수 (Variable) | 설명 (Description) | 예시 (Example) |
|---|
QUALITY_GATE_CONFIG | .quality-gate.yaml 또는 .quality-gate.json 파일의 절대 경로입니다. 설정 검색을 위해 상위 디렉토리를 탐색하는 것을 건너뜁니다. | /app/ci/quality-gate.yaml |
| ... | | |
자동 수정 (Auto-Fix)
Phase 1은 다음 이슈들을 자동으로 수정합니다:
ESLint 자동 수정 (~100+ 규칙)
// var → const/let
var x = 1 → const x = 1
...
AST 자동 수정(Auto-Fix)
// 불필요한 중괄호 제거 (단일 라인 if문)
if (x) { return true } → if (x) return true
Prettier 포맷팅
ESLint 수정 후, 일관된 포맷을 보장하기 위해 Prettier가 실행됩니다:
// ESLint는 중괄호를 제거하지만 어색한 포맷을 남깁니다:
if (x) return true
...
참고: Prettier는 MCP의 설정이 아닌 프로젝트 자체의 설정을 사용합니다.
나머지 모든 것: AI에 보고되면, AI가 수정합니다.
API
도구: quality_fix
// 입력
{
files: string[] // 검사할 파일 경로들
...
실패한 실행이 디스크에 남기는 것. 이 게이트는 적용할 수 있는 모든 수정 사항을 적용하고 유지합니다. 고칠 수 없는 발견 사항(린트 규칙, 사용자 정의 규칙, 변경해도 안전하다고 증명되지 않은 == 비교 등)은 success: false와 함께 remaining으로 반환됩니다. 유지된 수정 사항은 fixed에서 계산됩니다. 실행이 롤백되는 경우는 오직 수정기(fixer) 자체가 무언가를 망가뜨렸을 때뿐입니다 (예: 수정 후 타입 오류, 컴파일러가 거부하는 Vue 파일 등 ESLint 또는 Prettier의 실행 실패). 이 경우 fixed는 0이고 시도된 수정 사항은 attempted에 나열됩니다. 만약 그 롤백 자체가 실패한다면, 응답은 ROLLBACK_FAILED입니다: error.details.unrestoredFiles에는 여전히 수정 내용이 남아있을 수 있는 파일들이 나열되며, phase는 실패한 단계이고, remaining은 위치 정보 없이 실패한 내용을 나타냅니다. SonarQube(Phase 2) 발견 사항이나 도달할 수 없는 서버 역시 검증된 Phase 1의 수정 사항을 되돌리지 않습니다: 이들은 그대로 유지되고 발견 사항은 remaining으로 반환됩니다.
재시도. 만약 동일한 실패가 연속 세 번 동안 변경 없이 발생한다면 (동일 파일, 동일 내용, 동일 발견 사항), MCP 서버는 error.code: "PERSISTENT_FAILURE"와 함께 호출자에게 재시도를 중단하고 사람에게 문의하라고 알려줍니다. 파일을 변경하거나 발견 사항이 바뀌면 카운트가 다시 시작됩니다. fixedCount는 수정된 편집 내용만 계산하며, JSON 유효성 검사 통과는 fixed.json에 포함되며 수정 내용은 아닙니다.
중첩되는 호출(Overlapping calls). MCP 서버는 도착한 순서대로 파일 세트가 중첩되는 quality_fix 호출을 실행하므로, 한 호출의 롤백은 다른 호출이 유지한 편집 내용을 덮어쓰고 이전 버전을 복원할 수 없습니다. 서로 다른 파일을 대상으로 하는 호출들은 여전히 병렬로(side by side) 실행됩니다.
기능 플래그 (Feature Flags)
ENABLE_I18N_RULES
국제화(i18n)가 필요한 프로젝트의 경우, 리터럴 문자열 감지 기능을 활성화하십시오:
{
"env": {
"ENABLE_I18N_RULES": "true"
...
}
활성화 시:
<h1 >Hello World</h1 >
...
문제 해결 (Troubleshooting)
MCP: quality_fix가 나타나지 않는 경우
- Node.js 20.10 이상 또는 21.1 이상 —
node -v 및 npx --version을 실행하십시오.
mcp.json을 편집한 후 Cursor를 새로고침하거나(또는 MCP 새로고침 컨트롤 사용) 하십시오.
- JSON — 파일은 유효한 JSON이어야 합니다(후행 쉼표 없음). 확실하지 않은 경우 MCP 설정 섹션에서 복사하십시오.
- 전역 설치(Global install) — `