Skip to main content
Glama
dolrea77
by dolrea77
README.md
# inspection-mcp

개발 서버 화면 검수 자동화 MCP 서버.
검수 시트(자연어)를 Playwright 스크립트로 변환하고, 이후 반복 검수는 스크립트만 실행합니다.

---

## 설치

```bash
cd /유저경로/inspection-mcp

# 의존성 설치
npm install

# Playwright 브라우저 설치
npx playwright install chromium

# 빌드
npm run build
```

Node.js 18 이상이 필요합니다.

---

## MCP 서버 등록

### Claude Desktop

`~/Library/Application Support/Claude/claude_desktop_config.json` 파일을 편집합니다.

```json
{
  "mcpServers": {
    "inspection-mcp": {
      "command": "/노드설치경로/node",
      "args": ["/유저경로/inspection-mcp/dist/index.js"]
    }
  }
}
```

### Cursor

프로젝트 루트 또는 글로벌 `.cursor/mcp.json` 파일을 편집합니다.

```json
{
  "mcpServers": {
    "inspection-mcp": {
      "command": "/노드설치경로/node",
      "args": ["/유저경로/inspection-mcp/dist/index.js"]
    }
  }
}
```

### nvm 환경에서 node 경로 찾기

nvm을 사용하는 경우 심볼릭 링크가 아닌 절대 경로를 사용해야 합니다.

```bash
# 현재 node 절대 경로 확인
which node
# 예시 결과: /Users/유저이름/.nvm/versions/node/v20.11.0/bin/node
```

---

## 환경 설정

### .env 파일

프로젝트 루트에 `.env` 파일을 생성합니다. `.env.example`을 참고하세요.

```bash
cp .env.example .env
```

#### 사이트 등록

`QA_SITE_{사이트키}_URL` 패턴으로 자동 인식됩니다. 사이트키는 영문 대문자로 작성합니다.

```env
# 사이트 URL (필수)
QA_SITE_MARKET_URL="https://dev-market.example.com"
QA_SITE_MARKET_NAME=마켓

QA_SITE_BACKOFFICE_URL="https://dev-backoffice.example.com"
QA_SITE_BACKOFFICE_NAME=백오피스

# 외부 SSO 로그인 URL (선택 - SSO 리다이렉트 방식일 때만)
QA_SITE_BACKOFFICE_LOGIN_URL="https://sso.example.com/#/login"
```

#### 계정 등록

`QA_ACCOUNT_{계정키}_ID` / `_PW` 패턴으로 자동 인식됩니다.

```env
QA_ACCOUNT_USER_ID=your-username
QA_ACCOUNT_USER_PW=your-password

QA_ACCOUNT_MANAGER_ID=your-manager-id
QA_ACCOUNT_MANAGER_PW=your-manager-pw
```

#### 실행 옵션

```env
QA_HEADLESS=true          # true: 백그라운드 실행, false: 브라우저 표시
QA_TIMEOUT=30000          # 스크립트 타임아웃 (ms)
QA_SCREENSHOT_ON_PASS=false  # 성공 항목도 스크린샷 저장 여부
QA_MAX_CONCURRENCY=5      # 최대 동시 실행 수
```

### config.json

사이트별 로그인 셀렉터, 규칙 필터, 뷰포트를 설정합니다.

```json
{
  "sites": {
    "market": {
      "login": {
        "path": "/login",
        "spaWait": 2000,
        "selectors": {
          "idInput": "#loginId",
          "pwInput": "#loginPw",
          "submitButton": "button[type=submit]"
        },
        "successIndicator": "/main"
      }
    }
  },
  "ruleFilter": {
    "maxPageLoadTime": 10000,
    "minPageHeight": 200,
    "ignoreConsolePatterns": ["Warning:", "[HMR]", "Failed to load resource"],
    "ignoreNetworkPatterns": ["google-analytics.com", "googletagmanager.com"]
  },
  "viewport": {
    "width": 1440,
    "height": 900
  }
}
```

`.env`의 사이트키와 `config.json`의 사이트키는 **소문자로 일치**해야 합니다.
(예: `QA_SITE_MARKET_URL` → `config.json`에서 `"market"`)

---

## 사용법

### 1단계: 검수 시트 준비

먼저 템플릿을 받아 검수 항목을 작성합니다.

> "검수 시트 템플릿 받아줘"

AI가 `get_qa_template` 도구를 호출하여 엑셀 템플릿 경로를 알려줍니다.
템플릿을 복사하여 검수 항목을 작성합니다.

#### 엑셀 컬럼 구조

| 컬럼 | 필수 | 설명 | 예시 |
|------|------|------|------|
| id | O | 숫자 고유 ID | 1, 2, 3 |
| site | O | `.env` 사이트키 (소문자) | market, backoffice |
| path | 조건부 | 시작 페이지 경로 | /market, /product/list |
| group | - | 여정 그룹명 (같으면 순차 실행) | purchase_flow |
| description | O | 자연어 검수 내용 | 상품 검색 시 결과가 정확한지 확인 |
| account | 조건부 | `.env` 계정키 (소문자) | user, manager |
| type | - | full(기본) 또는 rule_only | full |
| login | - | yes(기본) 또는 no | yes |

- **독립 항목** (group 없음): `path` 필수
- **여정 그룹**: 첫 항목만 `path` 필수, 이후 항목은 이전 스크립트 실행 후 이어서 진행
- **login=yes**: `account` 필수
- **rule_only**: 스크립트 없이 HTTP 상태, 콘솔 에러, 페이지 높이 등만 검사

### 2단계: 검수 시트 등록

작성한 엑셀 파일을 `data/sheets/` 폴더에 넣습니다.

```
/유저경로/inspection-mcp/data/sheets/검수시트.xlsx
```

그 다음 AI에게 말합니다:

> "검수 항목 조회해줘"

`list_qa_items` 도구가 `data/sheets/` 폴더를 자동 스캔하여 새 파일을 등록하고 결과를 보여줍니다.

#### 여러 엑셀 파일 관리

- 파일 여러 개를 넣어도 됩니다 — 각각 독립적으로 관리됩니다
- 파일 수정 시 자동으로 변경 감지 후 재등록됩니다
- 파일 삭제 시 해당 항목들도 자동으로 삭제됩니다

### 3단계: 스크립트 생성

> "검수 스크립트 만들어줘"

AI가 각 항목에 대해:
1. `prepare_qa_item` — 대상 페이지의 DOM 구조를 수집
2. DOM 정보를 기반으로 Playwright 스크립트 작성
3. `save_qa_script` — 스크립트 검증 후 저장

저장된 스크립트는 `data/scripts/item-001.ts` (+ 컴파일된 `.js`) 형태입니다.

### 4단계: 검수 실행

> "검수 실행해줘"

```
전체 실행:     run_qa
특정 항목만:    run_qa (items: [1, 2])
특정 사이트만:  run_qa (sites: ["market"])
단일 디버깅:    run_qa_single (item_id: 1)
```

실행 결과:
- 성공/실패/에러/스킵 상태
- 실패 항목의 스크린샷 (AI 응답에 이미지로 포함)
- HTML/JSON 리포트: `data/reports/{실행ID}/`

### 이후 반복 검수

스크립트가 한 번 생성되면, 이후에는 "검수 실행해줘"만으로 반복 실행 가능합니다.
AI 토큰 소모 없이 스크립트만 실행됩니다.

---

## 탐지 가능한 이슈 유형

이 MCP 서버는 두 가지 방식으로 이슈를 탐지합니다.

### 자동 규칙 검사 (rule_only / full 모드 공통)

모든 검수 항목에 자동으로 적용되며, 별도 스크립트 작성 없이 탐지됩니다.

| 검사 항목 | 판정 기준 | 탐지 예시 |
|-----------|-----------|-----------|
| HTTP 상태 코드 | 400 이상이면 실패 | 404 Not Found, 500 Internal Server Error |
| 콘솔 에러 | `console.error` 1건 이상 발생 | JavaScript 런타임 에러, API 호출 실패 로그 |
| 깨진 이미지 | `<img>` 태그 로드 실패 | 삭제된 상품 이미지, 잘못된 이미지 경로 |
| 페이지 높이 | 200px 미만이면 실패 | 빈 페이지 렌더링, 데이터 로딩 실패로 컨텐츠 없음 |
| 네트워크 에러 | Fetch/XHR 요청 실패 | API 서버 다운, CORS 에러, 타임아웃 |
| 페이지 로드 시간 | 10초 초과 시 실패 | 서버 응답 지연, 무거운 리소스 로딩 |

> `config.json`의 `ruleFilter`에서 기준값과 무시 패턴을 설정할 수 있습니다.
> 예: HMR 경고, Google Analytics 에러 등 개발 환경 노이즈는 기본 제외됩니다.

### AI 스크립트 검사 (full 모드)

자연어 검수 내용을 기반으로 AI가 Playwright 스크립트를 생성하여 검증합니다. 사용자 관점의 UI/UX 이슈를 탐지할 수 있습니다.

**클릭/입력 인터랙션**
- 버튼 클릭 후 예상 동작 확인 (팝업 열림, 페이지 이동 등)
- 폼 입력 후 제출 결과 검증
- 탭/메뉴 전환 시 콘텐츠 변경 확인
- 예시: "상품명 클릭 시 상세보기 팝업이 열리는지 확인"

**텍스트/콘텐츠 검증**
- 특정 텍스트가 페이지에 노출되는지 확인
- 글자 깨짐, 인코딩 오류 탐지
- 데이터가 올바르게 표시되는지 검증
- 예시: "상품정보제공고시 화면에서 모든 속성값에 깨진 글자가 없는지 확인"

**검색/필터 기능**
- 검색 입력 후 결과 목록 노출 확인
- 필터 조건 적용 후 목록 갱신 검증
- 자동완성/최근 검색어 기능 동작 확인
- 예시: "검색어 입력 후 Like 검색 결과가 정확한지 확인"

**상태별 노출 제어**
- 특정 상태의 항목이 노출/미노출되는지 확인
- 권한에 따른 메뉴/버튼 표시 검증
- 예시: "판매중지/판매종료 상품이 목록에 미노출되는지 확인"

**페이지 네비게이션**
- 다음/이전 버튼으로 페이지 이동 확인
- URL 변경 패턴 검증
- 뒤로가기 후 상태 유지 확인
- 예시: "하단 '다음' 버튼을 눌러 다음 단계로 이동하는지 확인"

**요소 존재/가시성**
- 필수 UI 요소가 페이지에 존재하는지 확인
- 로딩 후 요소가 정상적으로 보이는지 검증
- 예시: "로그인 후 메인 페이지에 사용자 이름이 표시되는지 확인"

### 검수 유형 선택 가이드

| 상황 | 권장 유형 | 설명 |
|------|-----------|------|
| 페이지가 정상 로딩되는지만 확인 | `rule_only` | 스크립트 없이 HTTP/콘솔/이미지 자동 검사 |
| UI 동작을 구체적으로 검증 | `full` | 자동 규칙 검사 + AI 스크립트 검사 모두 적용 |
| 배포 후 전체 페이지 헬스체크 | `rule_only` | 빠르게 전 페이지 상태 확인 |
| 특정 기능의 정상 동작 확인 | `full` | 클릭/입력/검증 시나리오 스크립트 생성 |

---

## 도구 목록

| 도구 | 설명 |
|------|------|
| `register_qa_sheet` | 검수 시트 등록 (data/sheets/ 자동 스캔 또는 파일 경로 지정) |
| `list_qa_items` | 등록된 항목 조회 (조회 전 자동 동기화) |
| `get_qa_template` | 엑셀 템플릿 경로 반환 |
| `update_qa_item` | 항목 메타데이터 수정 (sheets 폴더 항목은 엑셀에서 수정 안내) |
| `delete_qa_item` | 항목 삭제 (sheets 폴더 항목은 엑셀에서 관리) |
| `prepare_qa_item` | 대상 페이지 DOM 수집 |
| `save_qa_script` | Playwright 스크립트 검증+저장 |
| `run_qa` | 전체/필터 검수 실행 |
| `run_qa_single` | 단일 항목 디버깅 실행 |

---

## 주의사항

### 검수 시트 관리

- `data/sheets/` 폴더에 넣은 엑셀 파일이 **단일 진실 원천**입니다
- 항목을 삭제하려면 엑셀에서 해당 행을 지운 뒤 저장하세요. `delete_qa_item`으로는 삭제되지 않습니다
- 항목을 수정하려면 엑셀을 직접 편집하세요. `update_qa_item`은 시트 관리 항목의 수정을 차단하고 엑셀 수정을 안내합니다
- 항목을 추가하려면 엑셀에 행을 추가하면 됩니다. 다음 도구 호출 시 자동으로 반영됩니다
- 엑셀 파일을 열어둔 상태에서 생기는 `~$` 임시 파일은 자동으로 무시됩니다

### 스크립트 규약

AI가 생성하는 스크립트는 이 프로젝트만의 규약을 따릅니다:
- `module.exports = async (page) => { ... }` 형태 (CommonJS)
- `page` 객체 하나만 인자로 받음 — `({ page, expect })` 구조분해 사용 불가
- `{ pass: boolean, message: string }` 객체를 반드시 반환
- `@playwright/test`, `require()` 등 외부 모듈 사용 불가
- 첫 페이지 이동은 실행기가 처리하므로, 스크립트는 추가 조작만 작성

### 환경 설정

- `.env`에 민감한 정보(계정 비밀번호 등)가 포함됩니다. git에 커밋하지 마세요 (gitignore 적용됨)
- `config.json`의 사이트키는 `.env`의 `QA_SITE_{키}_URL`에서 `{키}`를 소문자로 변환한 값과 일치해야 합니다
- nvm 환경에서는 MCP 등록 시 `which node`로 확인한 절대 경로를 사용하세요. `node`만 쓰면 PATH 문제로 실행이 안 될 수 있습니다

### 세션 및 인증

- 로그인 세션은 `data/auth-states/`에 저장됩니다. 세션 만료 시 자동으로 재로그인합니다
- WEHAGO 팝업 로그인 시 팝업 URL이 `wehago.com`을 포함하는지 검증합니다
- `data/auth-states/` 디렉토리는 `0700` 권한으로 생성됩니다

### 실행 관련

- `QA_HEADLESS=false`로 설정하면 브라우저가 화면에 표시됩니다. 디버깅에 유용합니다
- `scriptStatus`가 `ready`가 아닌 항목은 실행 시 자동으로 건너뜁니다 (skip)
- 여정 그룹은 같은 브라우저 페이지에서 순차 실행됩니다. 중간 항목의 선행 스크립트가 모두 `ready`여야 합니다
- 실행 결과 폴더명은 `날짜_시분초` 형식으로 생성됩니다:
  - `run_qa` → `data/screenshots/run-20260306_143025/`
  - `run_qa_single` → `data/screenshots/single-20260306_143025/`
  - 리포트도 동일한 ID: `data/reports/run-20260306_143025/`
- `run_qa` 결과에는 스크린샷 이미지가 포함되지 않습니다 (용량 초과 방지). 실패 항목의 스크린샷을 확인하려면 `run_qa_single`로 해당 항목을 재실행하세요

---

## 폴더 구조

```
inspection-mcp/
├── .env                  # 사이트 URL, 계정 정보 (git 제외)
├── .env.example          # 환경변수 템플릿
├── config.json           # 사이트별 로그인 셀렉터 설정
├── package.json
├── tsconfig.json
├── src/                  # 소스 코드
│   ├── index.ts          # MCP 서버 진입점
│   ├── types/index.ts    # 타입 정의
│   ├── core/             # 핵심 모듈
│   │   ├── config-loader.ts    # 환경변수/설정 로딩
│   │   ├── excel-parser.ts     # 엑셀 파싱
│   │   ├── script-generator.ts # 스크립트 생성/저장
│   │   ├── script-runner.ts    # 스크립트 실행
│   │   ├── rule-filter.ts      # 규칙 필터 (HTTP, 콘솔, 이미지 등)
│   │   ├── report-generator.ts # HTML/JSON 리포트
│   │   └── auth-manager.ts     # 로그인/세션 관리
│   ├── store/            # 데이터 저장소
│   │   ├── qa-store.ts         # qa-items.json CRUD
│   │   └── sheet-registry.ts   # 엑셀↔항목 매핑 + 동기화
│   └── tools/            # MCP 도구 핸들러 (9개)
├── dist/                 # 빌드 결과물 (git 제외)
└── data/                 # 런타임 데이터 (git 제외, 자동 생성)
    ├── sheets/           # 검수 시트 엑셀 파일 배치 폴더
    ├── scripts/          # 생성된 Playwright 스크립트
    ├── reports/          # 실행 리포트
    ├── screenshots/      # 실패 스크린샷
    └── auth-states/      # 로그인 세션 파일
```

TDQS

A4.2/5.0

Scored across 9 tools

Disambiguation5/5

Each tool targets a distinct operation in the QA workflow: registration, preparation, script saving, listing, template retrieval, update, delete, bulk run, and single run. The only potential overlap is between run_qa and run_qa_single, but their descriptions clearly distinguish bulk vs. single execution.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern in snake_case (register_, prepare_, save_, list_, get_, update_, delete_, run_). The shared 'run_qa' prefix for bulk and single execution is a minor but acceptable deviation.

Tool Count5/5

Nine tools cover the full QA lifecycle without redundancy. Each tool addresses a distinct step, from Excel registration to script debugging, and none feel extraneous.

Completeness4/5

The toolset covers the complete workflow: import, prepare, script, run, update, and delete. Minor gaps include a dedicated 'get_qa_script' to retrieve saved script contents and no historical run result retrieval, but these can be worked around via existing tools.

Maintenance

ActivityInactive
ResponsivenessNo issues