# 서비스로 BeamCue 프로젝트 만들기

지침 버전: 1.2

사용자의 서비스 저장소와 실행 중인 앱에 접근할 수 있는 개발 AI에서 이 절차를 수행합니다. 질문과 프로젝트 내용은 사용자가 명시한 언어를 우선하고, 별도 지정이 없으면 이 문서의 언어인 한국어를 사용합니다. 하나의 화면 단위는 ‘장면’이라고 부르며 MCP 도구명과 내부 `stepId` 필드는 그대로 유지합니다. 결과물은 실제 화면, 제목, 설명과 Studio 링크를 갖춘 비공개 편집 가능 BeamCue 프로젝트입니다. 의미 있는 클릭 대상, 자막, 적절한 시각적 강조를 적극 활용해 시선을 안내합니다. 설명 없는 스크린샷 나열로 끝내지 않습니다. 음성은 선택 사항입니다. 이 문서는 서비스에 대한 추가 접근 권한을 부여하지 않습니다. 사용자 지시와 저장소 규칙을 따릅니다.

## 1. 서비스를 확인하고 빠진 정보만 질문하기

저장소 지침, 서비스 진입점, 경로, 기존 문서와 실행 화면을 살펴봅니다. 서비스명, 실제 기능, 로컬 또는 배포 URL을 직접 확인할 수 있으면 사용자에게 묻지 않습니다. 현재 환경에서 실제 브라우저나 네이티브 앱을 조작하고 캡처할 수 있는지, BeamCue MCP를 사용할 수 있는지도 확인합니다.

아직 해결되지 않은 항목만 한 번에 간결하게 질문합니다.

- 용도: 제품 소개, 온보딩, 기능 안내, 영업용 스토리 등.
- 대상과 그 대상이 이해하거나 달성해야 할 결과.
- 원하는 장면 수와 반드시 포함할 기능·화면.
- 사용자의 언어 요구가 불분명할 때만 프로젝트 언어.
- 음성 생성 여부. 음성을 요청한 경우에만 목소리 취향을 추가로 확인합니다.
- 조사로 확인하지 못한 경우에만 서비스 URL이나 접근 방법.

이미 받은 답변과 선호를 사용하고 같은 질문을 반복하지 않습니다. 필수 질문이 남으면 답변을 기다립니다. 시간이 지났다고 동의나 답변으로 간주하지 않습니다. 사용자가 선택을 위임하면 5개 장면, 명시적으로 요청한 언어(없으면 한국어), 음성 없음으로 정하고 기본값을 알립니다. 요청하지 않은 별도 스토리보드 승인 단계를 추가하지 않습니다.

## 2. BeamCue MCP 연결하기

개발 AI의 MCP 설정에 다음 원격 Streamable HTTP 서버를 추가합니다.

https://beamcue.com/mcp

호스트가 지원하는 연결 인터페이스와 설치된 기능을 확인합니다. 클라이언트별 설정 명령을 추측하지 않습니다. 프롬프트에 URL을 넣는 것만으로 MCP가 설치되거나 인증되지는 않습니다. 직접 설정할 수 없으면 사용자에게 AI 도구에 URL을 추가하도록 안내한 뒤 이 대화를 이어갑니다. OAuth는 호스트와 사용자 브라우저가 처리합니다.

- 인증 서버: https://beamcue.com/o
- 보호 리소스 메타데이터: https://beamcue.com/.well-known/oauth-protected-resource/mcp
- 인증 서버 메타데이터: https://beamcue.com/.well-known/oauth-authorization-server/o
- 범위: `projects:read projects:write`
- S256 PKCE를 사용하는 Authorization Code 방식이며 콜백과 PKCE 값은 호스트가 제공합니다.

호출 전에 현재 도구와 스키마를 조회합니다. 호스트가 도구 이름에 접두사를 붙일 수 있습니다. `get_connection_status`를 호출하고, 프로젝트 변경 전에 `mcpConnectionStatus=connected`를 확인합니다. 연결이 없거나 만료되면 `begin_oauth` 또는 `get_reconnect_url`로 호스트의 OAuth를 다시 시작합니다. 웹사이트 로그인과 MCP OAuth는 별개이므로 웹 로그인만으로 만료된 MCP 인증이 복구되지는 않습니다. 대화로 비밀번호·토큰·PKCE 비밀값을 요청하거나 프롬프트·스크린샷·로그에 남기지 않습니다.

## 3. 장면을 계획하고 실제 화면 수집하기

용도와 요청한 수에 맞춰 장면 순서를 정합니다. 장면마다 전달할 핵심, 경로 또는 이동 동작, 필요한 화면 상태, 대상 요소(있는 경우), 제목, 짧은 설명, 시선 안내 계획을 정합니다. 무엇을 가리키고 설명할지, 어떤 결과를 보여줄지, MCP에서 적용할 효과와 Studio에서 편집할 효과를 구분합니다. 위임받은 5개 장면 소개는 진입 화면, 주요 작업 공간, 핵심 동작, 그 결과, 다른 유용한 기능이나 다음 행동을 담습니다. 실제로 존재하는 기능에 맞추며 빈 장면을 채우려고 기능을 만들지 않습니다.

가능하면 승인된 테스트 계정으로 실제 서비스를 조작합니다. 사용 가능한 브라우저·네이티브 캡처 도구나 사용자가 제공한 실제 스크린샷을 사용하고 저장소의 캡처 규칙을 지킵니다. BeamCue 저장소에서 Playwright 스크린샷은 비교용이며 프로젝트 원본 자산으로 사용할 수 없습니다. 생성 이미지, HTML 모형, 샘플 데이터, 코드 조각을 작동 중인 서비스의 증거로 쓰지 않습니다. MCP로 가져온 화면은 `producer=mcp.client`인 정적 이미지입니다. 확장 녹화라고 주장하거나 `chrome.tabs.captureVisibleTab`으로 표시하지 않습니다.

일관된 뷰포트를 선택하고 필요한 상태의 로딩이 끝난 뒤 캡처하며, 업로드 전 각 이미지를 확인합니다. 비밀값과 민감한 입력은 이미지·요청·로그·증거에 남기지 않습니다. 로그인, 결제, 권한 변경 등 중요한 작업에는 사용자의 기존 승인이 필요합니다. 로그인·캡처·필수 화면이 막히면 필요한 접근 조치나 실제 스크린샷을 구체적으로 요청하고 기다립니다. 필수 장면을 조용히 건너뛰거나 일부만 만든 프로젝트를 완료로 처리하지 않습니다.

대상 좌표는 업로드하는 바로 그 이미지의 왼쪽 위를 기준으로 실제 이미지 픽셀 단위로 측정합니다. CSS 픽셀을 쓰지 않습니다. 동작 대상이 없는 장면은 이미지 중앙, `labelMode=caption_only`, `presentation.clickEffectVisible=false`를 사용하고 `clickLabel`을 생략합니다. 클릭을 지어내지 않습니다. 짧은 제목과 별도의 설명을 쓰고 같은 문장을 여러 라벨에 반복하지 않습니다.

### 실제 작업을 따라갈 수 있도록 시선 안내하기

용도와 대상에 맞게 표현을 선택하고, 모든 효과를 사용자에게 설정하게 하거나 스토리보드를 다시 승인받지 않습니다. 지원하는 MCP 설정은 생성 과정에서 적용합니다. 승인된 Studio 접근이 있으면 보이는 컨트롤로 Studio 전용 효과도 조정하고 저장·미리보기로 확인합니다. 접근이 없으면 장면별 남은 편집을 인계에 적습니다. 계획만 세운 효과를 적용했다고 말하지 않습니다. MCP에 없는 기능을 우회하려고 프로젝트 JSON을 직접 바꾸거나 비공개 API를 호출하지 않습니다.

| 요소 | 시선 안내 방법 | 현재 적용 방법 |
| --- | --- | --- |
| 클릭 대상과 동작 라벨 | 사용해야 할 정확한 컨트롤을 가리킵니다. ‘여기를 클릭’보다 ‘날짜 범위 선택’처럼 동작과 대상을 씁니다. | `add_screen` / `update_screen`: 측정한 `clickXPixel`, `clickYPixel`, `clickLabel`, `labelMode=both` 또는 `hotspot_only`. |
| 자막 | 동작의 이유나 바뀐 결과를 한 문장으로 설명하고 소리가 없어도 이해되게 합니다. | `description`과 `labelMode=caption_only` 또는 `both`. 설명은 선택한 음성의 대본으로도 사용합니다. |
| 포인터 강조 | 복잡한 화면에서 다음 동작을 찾기 쉽도록 일관된 강조 포인터를 사용합니다. | `update_project`의 `pointerMode=highlighted`. 작은 컨트롤을 가리거나 산만하면 `standard`. |
| 클릭 효과와 강조 모양 | 실제 동작을 눈에 보이는 신호로 보강합니다. 개요·결과 화면의 이유 없는 점멸은 피합니다. | `presentation.clickEffectVisible=false`로 클릭 표시를 끕니다. `hotspotRadius`, `hotspotAnchor`로 크기·위치를 설정합니다. |
| 자막과 라벨 배치 | 대상·결과·내비게이션·다른 라벨을 가리지 않게 배치하고, 읽기 쉬운 대비와 일관된 글꼴·짧은 줄을 사용합니다. | `presentation.captionLayout`의 `placement`와 `point`(0–1 좌표)로 자막 위치를 설정합니다. 글꼴·색·클릭 라벨 배치는 Studio에서 편집합니다. |
| 확대 | 작지만 중요한 컨트롤이나 결과에 잠시 집중하되 주변 맥락을 남깁니다. | `presentation.zoomEnabled=true`, `zoomScale=1.16`처럼 설정합니다. 유용한 경우 1.12–1.20부터 시작합니다. |
| 시간과 전환 | 대상을 찾고 결과를 읽을 시간을 줍니다. 명확한 상태 변화에는 컷, 차분한 연결에는 크로스페이드, 연속성 설명에 도움이 될 때만 슬라이드·모프를 사용합니다. | `presentation.durationMs`, `transition`(`cut`, `crossfade`, `slide`, `morph`), `slideDirection`, `transitionAnchor`를 사용합니다. 모프에는 앵커가 필요합니다. 생략 시 기본값은 2400ms, 컷, 확대 꺼짐입니다. |
| 출력 프레임 | 화면을 불필요하게 축소하지 않으면서 브라우저·앱 맥락을 보여줍니다. | `update_project`의 `windowFrame=browser`, `app`, `none`. 캡처에 프레임이 이미 있으면 `none`. |
| 선택 음성과 여유 시간 | 시청 중 결과를 설명하고 말이 끝난 뒤 짧은 이해 시간을 줍니다. | 요청한 경우만 `set_narration` / `generate_voiceover`. `endPaddingMs` 범위는 0–10000이며 필요하면 400–800ms부터 시작합니다. |

`labelMode`는 설명 텍스트를 제어합니다. 다음 장면으로 가려면 클릭해야 하는지, 클릭 효과나 커서가 보이는지를 제어하지 않습니다. `both`는 대상 문구와 자막, `hotspot_only`는 대상 문구, `caption_only`는 자막을 표시하고 `none`은 두 종류를 모두 숨깁니다. 특히 `caption_only`는 클릭 효과를 끄지 않습니다. 실제 동작이 없는 장면은 자막만 사용하고 `presentation.clickEffectVisible=false`를 적용한 뒤 남아 있는 포인터도 미리보기로 확인합니다. 설정 저장은 MCP 응답으로 확인하고, Studio에 접근할 수 없으면 시각 검증을 미실시로 보고합니다. 이런 신호는 안내용 표현이며 실제 클릭 가능한 앱이나 분기형 스토리가 구현됐다는 증거가 아닙니다.

요청한 장면 수 안에서 **맥락 → 동작 → 결과 확인 → 다음 행동**으로 구성합니다. 아래 기능이 실제로 있는 보고서 서비스라면 다음처럼 만들 수 있습니다.

| 장면 | 캡처와 강조 | 문구 예시 |
| --- | --- | --- |
| 1. 맥락 | 실제 작업 공간 전체. 자막만 표시하고 동작 점멸 없이 맥락을 유지합니다. | 자막: ‘팀 보고서를 한곳에서 관리합니다.’ |
| 2. 동작 | 날짜 필터를 사용하기 전 화면. 실제 위치를 측정해 `both`와 강조 포인터를 적용하고 필요한 경우 `presentation`으로 조금 확대합니다. | 라벨: ‘날짜 범위 선택’, 자막: ‘비교하려는 기간으로 보고서를 좁힙니다.’ |
| 3. 결과 확인 | 실제 필터 결과. 자막만 표시하고 필터를 다시 누르기보다 달라진 결과에 집중합니다. | 자막: ‘차트에 선택한 기간의 데이터만 표시됩니다.’ |
| 4. 다음 동작 | 승인된 내보내기 전에 실제 내보내기 컨트롤을 캡처하고 짧은 라벨로 가리킵니다. | 라벨: ‘보고서 내보내기’, 자막: ‘현재 보기를 팀과 공유할 자료로 준비합니다.’ |
| 5. 이어가기 | 실제 완료 상태나 유용한 다음 목적지를 캡처하고 다음 행동을 명확히 합니다. | 버튼 클릭만으로 성공을 추정하지 말고 확인한 결과를 설명합니다. |

실제 서비스에 맞게 예시를 조정합니다. 컨트롤을 지어내거나 확인하지 않은 내보내기 성공을 주장하지 않습니다. `add_screen` 이미지는 한 시점의 정적 상태이며 동작 전후를 녹화한 것이 아닙니다. 변화가 필요하면 결과를 별도 계획된 장면으로 캡처합니다. 요청한 장면 수를 유지하고 수가 적으면 핵심 동작과 결과를 우선합니다. 한순간에 주된 강조는 하나만 사용합니다. 자막으로 대상을 가리거나 움직임을 늘리려고 확대·큰 클릭 효과·움직이는 문구를 겹치지 않습니다. 읽기 전용 서비스는 클릭을 만들지 말고 중요한 결과를 강조합니다.

## 4. 프로젝트 생성과 화면 추가하기

대화에 재개 기록을 남깁니다. 프로젝트 ID, Studio URL, 완료된 장면 ID·순서, 현재 리비전, 작업별 멱등성 키를 기록합니다. 이미지 Base64, 서명 URL, 인증 정보, 민감한 화면 내용은 기록하지 않습니다. 논리적으로 새로운 변경마다 고유한 키를 만들고 같은 변경을 재시도할 때는 입력과 키를 유지합니다. 새로운 요청에만 새 프로젝트를 만듭니다.

아래 JSON은 도구 인자 예시이며 실제 서비스의 증거가 아닙니다. 자리표시자는 직접 확인한 값으로 바꿉니다. `canvas`는 선택한 CSS 뷰포트이고 `output`은 지정할 경우 영상 크기와 fps를 설정합니다. `surface`는 웹사이트에서 `browser`, 네이티브 앱에서 `screen`입니다. `locale`은 결과물 언어에 맞게 명시합니다.

```json
{"tool":"create_project","arguments":{"title":"서비스 소개","surface":"browser","locale":"ko-KR","sourceUrl":"https://your-service.example/","canvas":{"width":1440,"height":900},"idempotencyKey":"<unique-create-key>"}}
```

반환된 `projectId`와 `studioUrl`을 보관하고, 요청하지 않은 음성은 끕니다.

```json
{"tool":"set_narration","arguments":{"projectId":"<projectId>","enabled":false,"idempotencyKey":"<unique-narration-settings-key>"}}
```

작업 안내에는 강조 포인터와 캡처에 맞는 프레임을 명시적으로 적용합니다.

```json
{"tool":"update_project","arguments":{"projectId":"<projectId>","pointerMode":"highlighted","windowFrame":"none","idempotencyKey":"<unique-presentation-key>"}}
```

실제 이미지와 같은 이미지에서 측정한 픽셀 좌표로 화면을 순서대로 추가합니다. `description`은 자막이자 음성이 켜진 경우 대본입니다. 설명 장면에는 `labelMode=caption_only`, 실제 대상을 가리킬 때는 `both`를 사용합니다. `narrationEnabled`는 사용자의 답변에 맞춥니다.

```json
{"tool":"add_screen","arguments":{"projectId":"<projectId>","title":"주요 작업 공간","description":"이 화면에서 실제로 할 수 있는 작업을 설명합니다.","clickXPixel":720,"clickYPixel":450,"labelMode":"caption_only","narrationEnabled":false,"imageFile":{"name":"workspace.png","mimeType":"image/png","dataBase64":"<actual-image-base64>"},"idempotencyKey":"<unique-scene-key>"}}
```

동작 장면에는 실제 대상과 라벨·자막을 모두 사용합니다. 아래 좌표는 예시이므로 확인한 이미지에서 다시 측정합니다. 제목은 대상 말풍선에 나올 수 있으므로 짧게 쓰고, `title`과 `clickLabel`을 같게 하면 중복 라벨을 피할 수 있습니다. 자막은 동작의 이점을 설명합니다.

```json
{"tool":"add_screen","arguments":{"projectId":"<projectId>","title":"날짜 범위 선택","clickLabel":"날짜 범위 선택","description":"비교하려는 기간으로 보고서를 좁힙니다.","clickXPixel":1060,"clickYPixel":184,"labelMode":"both","narrationEnabled":false,"imageFile":{"name":"date-filter.png","mimeType":"image/png","dataBase64":"<actual-image-base64>"},"idempotencyKey":"<unique-action-scene-key>"}}
```

대상이나 문구가 잘못된 장면은 기존 장면을 수정합니다.

```json
{"tool":"update_screen","arguments":{"projectId":"<projectId>","stepId":"<stepId>","title":"날짜 범위 선택","clickLabel":"날짜 범위 선택","description":"선택한 기간의 결과를 비교합니다.","clickXPixel":1060,"clickYPixel":184,"labelMode":"both","idempotencyKey":"<unique-action-correction-key>","presentation":{"clickEffectVisible":true,"zoomEnabled":true,"zoomScale":1.16,"durationMs":4000,"transition":"crossfade","captionLayout":{"placement":"bottom-center","point":{"x":0.5,"y":0.9}}}}}
```

`add_screen`, `update_screen`, `add_screens_batch.screens[]`의 `presentation`에 장면 설정을 전달합니다. 최상위 인자가 아닙니다. 수정 시 생략한 설정과 기존 자막 스타일은 유지됩니다. `captionLayout`은 `placement`와 `point`를 함께 지정합니다. 빈 객체·null 하위 값·알 수 없는 필드는 전달하지 않습니다. 전체 `labelMode` 변경은 장면별 재정의를 대체하지 않으므로 각 장면의 모드를 명시합니다.

### 이미지와 요청 제한

- 디코딩된 형식은 PNG, WebP, JPEG를 지원합니다. 각 변은 최대 8192px, 전체는 최대 64메가픽셀입니다.
- 인라인 이미지는 Base64 디코딩 후 최대 4MiB입니다. Base64는 크기를 약 1/3 늘리며 전체 MCP HTTP 요청은 8MiB 이하여야 합니다.
- `add_screens_batch`는 인라인 화면 1–20개를 원자적으로 추가하지만 같은 전체 요청 제한을 받습니다. 크기 예측과 재개가 쉬운 순차 `add_screen`을 우선하고 큰 이미지 20개를 한 요청에 넣지 않습니다.
- 큰 이미지는 `prepare_image_upload`로 최대 15MiB까지 준비합니다. `name`, `mimeType`, `byteLength`, `sha256`, `width`, `height`, `projectId`와 새 `idempotencyKey`를 전달합니다. 반환된 헤더를 사용해 `uploadUrl`에 정확한 이미지 바이트를 PUT합니다. 서명 URL은 10분 후 만료되며 일회용입니다. 이후 `add_screen`에는 `imageFile` 대신 `uploadId`를 전달합니다.
- MIME, 길이, SHA-256, 크기는 실제 이미지와 일치해야 합니다. 파일명 대신 디코딩된 바이트로 MIME을 확인합니다. `.png`로 저장해도 캡처 도구가 JPEG를 반환할 수 있습니다. Base64·서명 URL 인증값·이미지 바이트를 로그에 남기지 않습니다. 제한을 넘으면 적절한 뷰포트로 다시 캡처하거나 일관되게 리사이즈하고 크기·해시·대상 좌표를 다시 계산합니다.

수정은 `update_screen`, 순서 변경은 `reorder_screens`를 사용하고 중복 장면을 만들지 않습니다. 현재 도구 스키마의 필수 필드를 확인합니다. 응답에 `displayPreview.display`가 있으면 제목·클릭 라벨·자막의 중복 표시를 점검합니다.

## 5. 선택한 음성 생성하기

사용자가 요청한 경우에만 `set_narration`으로 음성을 켜고 요청 언어와 지원되는 목소리를 설정하며 해당 장면의 내레이션을 켭니다. 선호가 없으면 지원되는 기존 기본 목소리를 사용하고 음성 ID를 만들지 않습니다. 설명 확정 후 `generate_voiceover`를 `operation=generate-stale`로 호출하고 `get_narration_status`로 완료를 확인합니다. 음성 실패나 대기 작업은 따로 보고하고 Studio에서 수정할 수 있도록 프로젝트를 유지합니다.

## 6. 복구와 재개

- 연결 실패나 불확실한 응답 뒤에는 필요하면 재연결하고 `get_project`로 기존 프로젝트를 확인합니다. 원래 입력과 멱등성 키로 같은 변경을 재시도하고 새 프로젝트를 무작정 만들지 않습니다.
- `expectedRevision`은 선택 사항이며 단순 순차 작업에서는 생략합니다. 사용 중 리비전 충돌이 나면 구조화된 오류를 읽고 프로젝트 상태를 갱신한 뒤 반환된 재시도 리비전과 같은 논리적 입력·키를 사용합니다. 사용자 편집을 보존하고 요청과 충돌하면 덮어쓰기 전에 질문합니다.
- 서명 업로드가 만료되면 새 업로드 작업 키로 다시 준비합니다. 실패한 장면 추가 요청을 다른 `uploadId`로 바꿀 때는 이전 작업이 장면을 만들지 않았음을 확인한 뒤 새 장면 추가 키를 사용합니다.
- 필수 접근이나 캡처가 없으면 빠진 장면과 필요한 조치를 간결하게 질문으로 남깁니다. 완료된 내용과 Studio 링크를 보존해 처음부터 다시 만들지 않고 이어갑니다.

## 7. 검증과 전달

`get_project`로 실제 장면 수·순서·제목·설명·음성 상태를 요청과 비교하고 차이를 수정합니다. 각 장면의 정확한 동작 대상, 구별되는 동작·결과 문구, 적절한 라벨 모드, 포인터·프레임 적용도 시선 안내 계획과 대조합니다. 이후 정규 프로젝트를 검증합니다.

```json
{"tool":"get_project","arguments":{"projectId":"<projectId>"}}
```

```json
{"tool":"validate_project","arguments":{"projectId":"<projectId>","idempotencyKey":"<unique-validation-key>"}}
```

반환된 `studioUrl` 또는 `open_studio` 동작의 `nextAction.url`을 사용하고 프로젝트 URL을 추측하지 않습니다. 승인된 브라우저 접근이 있으면 실제 Studio 장면 목록과 미리보기에서 가져온 화면·자막을 확인합니다. 장면 경계를 넘겨 재생하며 클릭 신호가 의도한 컨트롤에 놓이는지, 결과 화면에 실제 변화가 있는지, 자막이 읽히고 대상을 가리지 않는지, 확대가 중요 UI를 잘라내지 않는지 확인합니다. 데스크톱과 작은 미리보기 크기 모두 점검합니다. 음성이 꺼진 경우를 포함한 읽기 시간, 전환 경고, Studio 전용 편집이 저장·새로고침 후 유지되는지도 확인합니다. 준비 완료로 보고하기 전에 빽빽한 문구를 줄이고 효과를 단순화합니다. Studio 로그인이 없으면 MCP 검증과 시각 검증을 구분해 보고하고 사용자에게 링크 검토를 요청합니다. 시각 검증을 했다고 주장하지 않습니다.

마지막에 프로젝트 제목, 완료/요청 장면 수, 짧은 장면 목록, 적용한 시각적 안내, 음성 상태, Studio 링크, 남은 조치를 전달합니다. 적용한 MCP 설정, Studio에서 눈으로 확인한 조정, 장면별 남은 조정을 구분합니다. 필수 화면과 설명이 모두 있을 때만 요청한 프로젝트를 완료로 처리합니다.

`validate_project`는 Studio 편집을 위한 검증과 준비를 수행하며 게시·음성 생성·영상 렌더링은 하지 않습니다. MCP에는 영상 렌더링 도구가 없습니다. 프로젝트를 비공개로 유지하고 사용자가 Studio에서 미리보기·편집·MP4 렌더링·공유를 선택하게 합니다. 프로젝트 검증 성공만으로 공개 링크나 영상 파일이 생겼다고 말하지 않습니다.
