npm package: @opsnow-mcp/opsnow-mcp-prototype-capture
Description: MCP server for capturing prototype pages and extracting DOM structure
Author: OpsNow
Latest version: 1.7.8

# Prototype Capture MCP Server

프로토타입 페이지를 캡처하고 DOM 구조를 추출하는 MCP 서버입니다.

## 도구

### `captureWithDOM`

페이지를 섹션별로 캡처하고 각 이미지에 해당하는 DOM 구조를 반환합니다.

#### 파라미터

| 파라미터 | 타입 | 필수 | 설명 |
|---------|------|------|------|
| webflowUrl | string | O | 프로토타입 URL |
| componentPath | string | O | 컴포넌트 생성 경로 (예: /src/components/dashboard) |
| targetPath | string | X | 캡처할 경로 (예: "/dashboard") |
| maxDepth | number | X | DOM 트리 최대 깊이 (기본값: 3) |
| loginCredentials | object | X | 로그인 인증 정보 (username, password, mfaCode) |
| waitTimeout | number | X | 페이지 로딩 대기 시간 (기본값: 60000ms) |
| waitForSelectors | array | X | 로딩 완료 확인할 CSS 선택자 목록 |
| debugLoading | boolean | X | 로딩 과정 디버그 메시지 표시 (기본값: false) |

### `refreshAllCaptures`

프로젝트의 모든 컴포넌트 이미지를 최신화합니다. 자동으로 images/ 폴더가 있는 컴포넌트를 찾아 재캡처합니다.

#### 파라미터

| 파라미터 | 타입 | 필수 | 설명 |
|---------|------|------|------|
| webflowUrl | string | O | 프로토타입 URL |
| componentsPath | string | O | 컴포넌트들이 있는 최상위 디렉토리 (예: /src/components) |
| maxDepth | number | X | DOM 트리 최대 깊이 (기본값: 3) |

#### 동작 방식

1. `componentsPath` 하위의 모든 디렉토리 스캔
2. `images/` 폴더가 있는 컴포넌트 자동 감지
3. 디렉토리 이름으로 라우트 추론 (예: `dashboard` → `/dashboard`)
4. 각 컴포넌트를 순회하며 이미지 재캡처

## 주요 기능

### 🔐 인증 처리
- **로그인 자동화**: 자격 증명 자동 입력
- **MFA/OTP 지원**: 2단계 인증 코드 처리
- **세션 재사용**: 쿠키 저장 및 재사용으로 반복 로그인 방지

### ⏳ 고급 로딩 대기
- **프레임워크 감지**: React, Vue, Angular, Next.js 자동 감지
- **동적 콘텐츠**: AJAX/Fetch 요청 완료 대기
- **로딩 인디케이터**: 스피너, 스켈레톤 UI 감지
- **리소스 로딩**: 이미지, 폰트 완전 로딩 대기
- **콘텐츠 안정화**: DOM 변경이 멈출 때까지 대기

## 동작 과정

### 1단계: 브라우저 실행 및 페이지 로드

```
Playwright Chromium 브라우저 실행
  ↓
뷰포트 설정 (1920x1080, 2x 스케일)
  ↓
대상 URL로 이동
  ↓
고급 로딩 대기 (프레임워크, AJAX, 리소스 등)
  ↓
네트워크 안정화 및 콘텐츠 안정화 대기
```

### 2단계: 섹션 감지

페이지에서 시맨틱 HTML 태그를 찾아 섹션을 식별합니다.

```javascript
// 감지 대상 태그
'header, nav, main, section, article, aside, footer'
```

각 섹션에 대해:
- XPath 생성
- 위치/크기 정보 수집
- DOM 트리 구축

### 3단계: DOM 트리 구축

각 섹션의 DOM 구조를 간결하게 추출합니다.

```
섹션 요소
  ↓
자식 요소 순회 (깊이 제한: maxDepth)
  ↓
각 요소에서 추출:
  - tag: 태그명
  - id: ID (있는 경우)
  - class: 클래스명 (최대 2개)
  - component: 컴포넌트 타입 (감지된 경우)
  - children: 자식 요소 (최대 5개, 초과 시 more 필드로 표시)
```

### 4단계: 컴포넌트 타입 감지

DOM 요소를 분석하여 UI 컴포넌트 타입을 자동 감지합니다.

| 컴포넌트 | 감지 조건 |
|---------|----------|
| `data-grid` | table 태그, .grid, .table 클래스 |
| `card` | .card 클래스 |
| `chart` | .chart 클래스, canvas/svg 포함 |
| `form` | form 태그, input/select/textarea 3개 이상 |
| `button` | button 태그, .button 클래스 |
| `nav` | nav 태그 |
| `sidebar` | aside 태그, .sidebar 클래스 |
| `tabs` | .tab 클래스 |

### 5단계: 스크린샷 캡처

각 섹션을 개별 JPEG 이미지로 저장합니다.

```
섹션별 좌표로 영역 선택
  ↓
page.screenshot() with clip 호출
  ↓
JPEG 형식, quality: 85
  ↓
파일명: {componentName}-header.jpg, {componentName}-main.jpg, ...
(예: dashboard-header.jpg, dashboard-main.jpg)
```

**파일명 규칙:**
- 일반 섹션: `{componentName}-{section}.jpg`
- 분할된 섹션 (3000px 초과): `{componentName}-{section}-{chunkNumber}.jpg`

### 6단계: 결과 반환

JSON 형식으로 결과를 반환합니다.

## 반환 형식

```json
{
  "url": "https://example.webflow.io/dashboard",
  "title": "Dashboard - Example",
  "outputDir": "/path/to/project/src/components/dashboard/images",
  "images": [
    {
      "file": "dashboard-header.jpg",
      "path": "/full/path/to/dashboard-header.jpg",
      "section": "header",
      "dom": {
        "tag": "header",
        "class": "site-header",
        "children": [
          {
            "tag": "nav",
            "component": "nav",
            "children": [
              { "tag": "a", "class": "logo" },
              { "tag": "ul", "class": "nav-links" }
            ]
          }
        ]
      }
    },
    {
      "file": "dashboard-main.jpg",
      "path": "/full/path/to/dashboard-main.jpg",
      "section": "main",
      "dom": {
        "tag": "main",
        "id": "content",
        "children": [
          {
            "tag": "section",
            "class": "card-grid",
            "component": "card",
            "children": [
              { "tag": "div", "class": "card" },
              { "tag": "div", "class": "card" },
              { "tag": "div", "class": "card" }
            ],
            "more": 2
          },
          {
            "tag": "div",
            "class": "chart-container",
            "component": "chart"
          }
        ]
      }
    },
    {
      "file": "dashboard-footer.jpg",
      "path": "/full/path/to/dashboard-footer.jpg",
      "section": "footer",
      "dom": {
        "tag": "footer",
        "children": [
          { "tag": "div", "class": "footer-links" },
          { "tag": "p", "class": "copyright" }
        ]
      }
    }
  ]
}
```

## DOM 구조 필드 설명

| 필드 | 타입 | 설명 |
|------|------|------|
| `tag` | string | HTML 태그명 |
| `id` | string | 요소 ID (있는 경우만) |
| `class` | string | 클래스명 (최대 2개, 공백 구분) |
| `component` | string | 감지된 컴포넌트 타입 |
| `children` | array | 자식 요소 배열 (최대 5개) |
| `more` | number | 생략된 자식 요소 수 |

## 사용 예시

### 메인 프로젝트에서 사용 (권장)

컴포넌트를 생성하면서 동시에 이미지 캡처:

```
프로젝트에서 /src/components/dashboard에 대시보드 컴포넌트를 만들어줘.
이미지는 captureWithDOM으로 캡처해서 같이 넣어줘.
- componentPath: {프로젝트절대경로}/src/components/dashboard
- targetPath: /dashboard
```

Claude가 자동으로:
1. `/src/components/dashboard/` 디렉토리 생성
2. 컴포넌트 파일 생성
3. `/src/components/dashboard/images/` 에 스크린샷 저장

### 직접 호출

```javascript
captureWithDOM({
  webflowUrl: "https://example.webflow.io",
  componentPath: "/Users/username/project/src/components/dashboard",
  targetPath: "/dashboard"
})
```

### 로그인이 필요한 페이지 캡처

로그인이 필요한 페이지를 캡처할 때는 `loginCredentials`를 전달하면 자동으로 로그인을 시도합니다:

```javascript
captureWithDOM({
  webflowUrl: "https://example.webflow.io",
  componentPath: "/Users/username/project/src/components/dashboard",
  targetPath: "/dashboard",
  loginCredentials: {
    username: "your-username",
    password: "your-password"
  }
})
```

**메인 프로젝트에서 사용:**
```
로그인이 필요한 대시보드 페이지를 캡처해줘.
- 아이디: admin@example.com
- 비밀번호: mypassword123
```

**동작 방식:**
1. 페이지 접속 후 로그인 폼 자동 감지
2. username/email 필드와 password 필드에 자동 입력
3. 로그인 버튼 클릭 또는 Enter 키 입력
4. 로그인 완료 후 대상 페이지로 이동
5. 페이지 캡처 및 DOM 구조 추출

### DOM 깊이 조절

```javascript
// 더 상세한 DOM 구조
captureWithDOM({
  componentPath: "/path/to/component",
  targetPath: "/dashboard",
  maxDepth: 5
})

// 간략한 DOM 구조
captureWithDOM({
  componentPath: "/path/to/component",
  targetPath: "/dashboard",
  maxDepth: 2
})
```

### 전체 이미지 갱신

프로젝트의 모든 컴포넌트 이미지를 한 번에 최신화:

```javascript
refreshAllCaptures({
  webflowUrl: "https://example.webflow.io",
  componentsPath: "/Users/username/project/src/components"
})
```

**실행 결과:**
```
/src/components/ 스캔
├── dashboard/images/ ✓ → /dashboard 재캡처
├── settings/images/  ✓ → /settings 재캡처
├── profile/images/   ✓ → /profile 재캡처
└── common/           ✗ images 없음, 스킵
```

**메인 프로젝트에서 사용:**
```
모든 컴포넌트 이미지를 최신화해줘
- refreshAllCaptures 사용
- componentsPath: {프로젝트절대경로}/src/components
```

## 설정

### `.mcp.json` 설정

```json
{
  "mcpServers": {
    "opsnow-mcp-prototype-capture": {
      "command": "node",
      "args": [
        "/path/to/mcp-servers/opsnow-mcp-prototype-capture/index.js"
      ],
      "env": {
        "WEBFLOW_URL": "https://example.webflow.io"
      }
    }
  }
}
```

**환경변수 설명:**
- `WEBFLOW_URL`: Webflow 프로토타입 URL (필수)
- `COMPONENT_PATH`: 기본 컴포넌트 경로 (선택, 파라미터로 전달 권장)

## 출력 파일 구조

```
{componentPath}/images/
├── dashboard-header.jpg
├── dashboard-nav.jpg
├── dashboard-main.jpg
├── dashboard-main-1.jpg (분할된 경우)
├── dashboard-main-2.jpg (분할된 경우)
├── dashboard-aside.jpg
└── dashboard-footer.jpg
```

**예시:** `componentPath: /src/components/dashboard`
```
/src/components/dashboard/
├── index.tsx
├── Dashboard.tsx
└── images/
    ├── dashboard-header.jpg
    ├── dashboard-main.jpg
    └── dashboard-footer.jpg
```

## 설계 원칙

1. **컨텍스트 최소화** - 마크다운 설명 없이 JSON만 반환
2. **구조화된 데이터** - AI가 파싱하기 쉬운 형식
3. **이미지-DOM 매핑** - 각 이미지가 어떤 DOM 구조인지 명확
4. **컴포넌트 감지** - UI 컴포넌트 타입 자동 식별

## 설치

### 팀원용 설치 가이드 (권장)

npm registry에 배포된 패키지를 사용하면 저장소 클론 없이 바로 사용할 수 있습니다.

1. **Claude Desktop 설정**

`~/Library/Application Support/Claude/claude_desktop_config.json` 파일을 열어 다음 설정을 추가합니다:

```json
{
  "mcpServers": {
    "opsnow-mcp-prototype-capture": {
      "command": "npx",
      "args": [
        "-y",
        "@opsnow-mcp/opsnow-mcp-prototype-capture"
      ],
      "env": {
        "WEBFLOW_URL": "https://your-webflow-url.webflow.io"
      }
    }
  }
}
```

**설정 수정사항:**
- `WEBFLOW_URL`: 팀에서 사용하는 Webflow URL로 변경

2. **Claude Desktop 재시작**

설정을 저장한 후 Claude Desktop을 완전히 종료하고 재시작합니다.

3. **설치 확인**

Claude Desktop에서 다음과 같이 테스트:
```
captureWithDOM으로 프로토타입 캡처해줘
```

**참고:**
- `npx`가 자동으로 패키지를 다운로드하고 실행합니다
- 처음 실행 시 Playwright Chromium이 자동으로 설치됩니다
- 패키지 업데이트 시 자동으로 최신 버전을 사용합니다

### 로컬 개발용 설치

```bash
# 저장소 클론
git clone https://github.com/opsnow-common/opsnow-mcp-prototype-capture.git
cd opsnow-mcp-prototype-capture

# 의존성 설치
npm install
npx playwright install chromium

# 로컬에서 실행
npm start
```

## npm 배포 가이드

### Private npm Registry에 배포

1. **npm registry 설정 확인**
```bash
# 현재 registry 확인
npm config get registry

# OpsNow private registry로 변경 (필요한 경우)
npm config set registry https://your-npm-registry.com
```

2. **로그인**
```bash
npm login
```

3. **배포**
```bash
# 패키지 배포
npm publish

# 특정 태그로 배포
npm publish --tag beta
```

4. **버전 업데이트 후 재배포**
```bash
# 패치 버전 올리기 (2.0.0 -> 2.0.1)
npm version patch

# 마이너 버전 올리기 (2.0.0 -> 2.1.0)
npm version minor

# 메이저 버전 올리기 (2.0.0 -> 3.0.0)
npm version major

# 배포
npm publish
```

### 배포 후 팀원 사용

팀원들은 별도 설치 없이 Claude Desktop 설정만 추가하면 바로 사용 가능합니다:

```json
{
  "mcpServers": {
    "opsnow-mcp-prototype-capture": {
      "command": "npx",
      "args": ["-y", "@opsnow-mcp/opsnow-mcp-prototype-capture"],
      "env": {
        "WEBFLOW_URL": "https://your-webflow-url.webflow.io"
      }
    }
  }
}
```

## 라이선스

MIT