Skip to content
Back to skills

Appstore Publish

ASecurity

mimi-seed MCP로 App Store Connect에 릴리스 노트와 스크린샷을 업로드한다. Use when publishing iOS App Store metadata updates via mimi-seed MCP in Claude Code or Codex.

  • 22 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 27, 2026
developmentbashapi

Works with

  • claude code
  • api
  • mcp

Security analysis

A100/100

Scanned October 5, 2026

npx -y skills add jeonghwanko/mimi-seed-sdk --skill appstore-publish --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Appstore Publish?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Appstore Publish
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/jeonghwanko-appstore-publish/badge)](https://www.skillsdirectory.com/skills/jeonghwanko-appstore-publish)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: appstore-publish
description: mimi-seed MCP로 App Store Connect에 릴리스 노트와 스크린샷을 업로드한다. Use when publishing iOS App Store metadata updates via mimi-seed MCP in Claude Code or Codex.
---

# appstore-publish

mimi-seed MCP 서버(`@yoonion/mimi-seed-mcp`)의 App Store 도구를 사용해 App Store Connect 메타데이터와 스크린샷을 업로드한다. 프로젝트 중립 스킬이며, 각 프로젝트의 `AGENTS.md` 또는 `CLAUDE.md`에 있는 iOS 스크린샷 매니페스트와 What's New 위치를 참고한다.

## 사전 조건

1. MCP 클라이언트(Claude Code / Codex 등)에 `mimi-seed`가 등록되어 있어야 한다.
2. App Store Connect API 인증 파일 `~/.mimi-seed/appstore.json`이 있어야 한다.
3. 대상 버전은 `PREPARE_FOR_SUBMISSION`, `DEVELOPER_REJECTED`, `METADATA_REJECTED`, `REJECTED` 중 하나여야 한다.

미인증이면 사용자에게 **터미널에서** 아래를 실행하라고 안내한다 (대화형이라 네가 대신 실행할 수 없다):

```bash
mimi-seed setup            # 안 된 계정만 순서대로 연결. `?` 를 누르면 토큰 발급 방법을 알려준다
mimi-seed auth appstore    # App Store Connect 만 따로
```

App Store Connect 는 Issuer ID · Key ID · `.p8` 파일 3개가 필요하고, **`.p8` 은 딱 한 번만 다운로드된다**.
발급 절차: [`docs/credentials.md`](../../docs/credentials.md) 의 "App Store Connect" 섹션

## 도구 로딩

호출 전 schema 로드:

```
ToolSearch(query="select:appstore_list_apps,appstore_list_versions,appstore_create_version,appstore_update_version_string,appstore_get_metadata,appstore_update_whats_new,appstore_list_builds,appstore_attach_build,appstore_submit_for_review,appstore_check_submission_risks,appstore_plan_release,appstore_list_app_info_localizations,appstore_list_screenshots,appstore_upload_screenshot,appstore_delete_screenshot_set,screenshot_validate")
```

승인 이후 출시 제어까지 다룰 때 추가로:

```
ToolSearch(query="select:appstore_release_status,appstore_release_version,appstore_update_release_type,appstore_phased_release")
```

심사 묶음이나 인앱 상품까지 다룰 때 추가로:

```
ToolSearch(query="select:appstore_list_review_submissions,appstore_add_version_to_review_submission,appstore_remove_review_submission_item,appstore_cancel_review,appstore_list_products,appstore_update_product_review_note,appstore_upload_product_review_screenshot,appstore_add_product_to_review")
```

## 실행 흐름

1. 프로젝트의 `AGENTS.md`를 먼저 읽고, 없으면 `CLAUDE.md`에서 iOS 매니페스트와 What's New 경로를 찾는다.
2. 로컬 버전은 힌트로만 사용한다. 실제 업로드 대상은 App Store Connect의 버전 목록을 기준으로 정한다.
3. 앱 목록에서 bundle id가 일치하는 앱을 찾는다.
4. 편집 가능한 버전과 localization id를 확인한다.
5. 사용자에게 `versionString`, `versionId`, `state`, `localizationId`, 업로드할 파일 목록을 보고하고 승인받는다.
6. What's New를 업데이트한다.
7. 스크린샷 교체 요청이 있으면 기존 screenshot set을 삭제한 뒤 매니페스트 순서대로 업로드한다.
   삭제 도구(`appstore_delete_screenshot_set` 등)는 먼저 `confirm` 없이 호출해 dry-run preview 를 받고,
   5단계 승인 범위에 그 셋이 포함돼 있을 때만 같은 인자 + `confirm: true` 로 다시 호출한다.
8. 빌드 연결은 `appstore_attach_build` — `buildId` 를 생략하면 최신 VALID 빌드를 붙인다.
9. 심사 제출(`appstore_submit_for_review`)도 같은 순서다: `confirm` 없이 호출 → preview(버전·빌드·whatsNew)를
   사용자에게 보여 명시 승인 → `confirm: true` 로 재호출.
10. 적용 결과와 실패 지점을 요약한다.

## 심사 제출 묶음 — 제출·재제출이 막힐 때

ASC는 버전을 바로 제출하지 않고 **심사 제출 묶음(reviewSubmission)** 을 제출한다. 묶음 항목으로 버전과
인앱 상품이 함께 들어간다. "제출이 안 된다"의 대부분은 버전이 아니라 묶음 문제이고, 이때 버전 자체는
`PREPARE_FOR_SUBMISSION`으로 멀쩡해 보인다. 막히면 추측하지 말고 `appstore_list_review_submissions`부터
읽는다 — 묶음 state(`READY_FOR_REVIEW` 초안 / `WAITING_FOR_REVIEW` 큐 / `UNRESOLVED_ISSUES` 거절 미해결 /
`COMPLETE`)와 항목이 보인다.

| 오류 | 원인 | 대응 |
| --- | --- | --- |
| `appStoreVersions ... is not in valid state` | 거절된 `UNRESOLVED_ISSUES` 묶음이 버전을 물고 있다 | `appstore_remove_review_submission_item`으로 항목을 푼다 (`appstore_submit_for_review`가 자동 시도하므로, 실패했을 때만 직접) |
| 409 `an appStoreVersions must be included in this review submission` | 웹에서 IAP를 담아 상품만 든 묶음이 생겼다 | `appstore_add_version_to_review_submission`으로 버전을 그 묶음에 넣는다. 버전이 다른 묶음에 물려 있으면 먼저 푼다 — 미제출이면 항목 제거, 제출된 묶음이면 `appstore_cancel_review` |
| 409 `cannot create a new version in the current state` | 편집 가능한 버전이 이미 있다 | 새로 만들지 말고 `appstore_update_version_string`으로 기존 레코드 이름을 올린다 |

빌드는 `CFBundleShortVersionString`이 같은 버전에만 붙는다. 새 빌드를 attach하기 전에 버전 문자열을 맞춘다.

## TestFlight 외부 테스트

내부 테스터는 처리 완료 즉시 받지만 외부 테스터는 Apple 베타 심사를 통과해야 한다. 심사 항목이 앱 단위와
빌드 단위로 갈려 있어 하나라도 비면 막힌다. 순서는 항상 상태 조회부터다.

```
ToolSearch(query="select:appstore_beta_status,appstore_update_beta_review_detail,appstore_update_beta_test_info,appstore_update_whats_to_test,appstore_submit_beta_review,appstore_set_beta_group_build,appstore_add_beta_testers,appstore_notify_beta_testers,appstore_declare_encryption")
```

1. `appstore_beta_status`(buildId + appId) — 외부 상태와 빈 필드를 확인한다.
2. 빈 것을 채운다: 심사 정보 → `appstore_update_beta_review_detail`(로그인 앱이면 데모 계정 필수),
   테스트 정보 → `appstore_update_beta_test_info`, What to Test → `appstore_update_whats_to_test`.
3. `appstore_submit_beta_review` — dry-run으로 블로커를 보고한 뒤 승인받고 confirm.
4. 승인 후 `appstore_set_beta_group_build`로 외부 그룹에 배포 (**이 순간 테스터에게 나간다**).
5. 초대·알림은 `appstore_add_beta_testers` / `appstore_notify_beta_testers` — 둘 다 메일이 즉시 나가므로
   대상 목록을 사용자에게 확인받고 실행한다.

`MISSING_EXPORT_COMPLIANCE`는 TestFlight가 아니라 수출 규정 문제다 → `appstore_declare_encryption`.

## 승인 이후 출시

버전 생성 때 `releaseType`을 `AFTER_APPROVAL`로 잡아두면 승인과 동시에 자동 출시되므로 아무 것도 할 게 없다.
아래는 그렇게 안 해뒀거나, 출시 속도를 조절해야 할 때다. 손대기 전에 `appstore_release_status`로 현재
상태(appStoreState · releaseType · 단계적 출시 진행도)를 먼저 읽는다.

- `PENDING_DEVELOPER_RELEASE`로 대기 중 → `appstore_release_version` (**confirm 필요**, 즉시 공개·비가역)
- `MANUAL`로 만들어 둔 걸 "승인되면 자동"으로 → `appstore_update_release_type`
- 7일에 걸쳐 점진 출시 → `appstore_phased_release` (`enable` / `pause` / `resume`)
- 남은 사용자에게 즉시 전체 공개 → `appstore_phased_release` `action=complete` (**confirm 필요**, 비가역)

Play의 `userFraction`·`halted`에 대응하는 iOS 장치다. 두 스토어를 함께 내보낼 때 출시 속도를 맞추려면
양쪽 다 조절해야 한다.

## 인앱 상품 심사 정보

앱 첫 심사에는 IAP도 함께 들어간다. `appstore_list_products`로 상태를 읽고, 심사 노트는
`appstore_update_product_review_note`, 심사용 스크린샷은 `appstore_upload_product_review_screenshot`(절대경로),
묶음 편입은 `appstore_add_product_to_review`로 처리한다. 상품 자체를 만들거나 지우는 작업은 요청받았을 때만 한다.

## 안전 규칙

- 스토어 쓰기 작업 전에는 반드시 사용자 승인을 받는다.
- 기존 스크린샷 셋 삭제는 되돌릴 수 없으므로 삭제 수량과 업로드 수량을 먼저 알린다.
- 파일 경로는 절대경로로 넘긴다. 이미지 바이트를 대화 컨텍스트에 싣지 않는다.
- `appstore_submit_for_review`와 `appstore_cancel_review`는 **같은 턴의 명시 승인**이 있을 때만 호출한다.
  제출 전에는 `appstore_check_submission_risks` 결과를 체크리스트로 먼저 보고한다. 취소는 항목 하나가 아니라
  묶음 전체를 심사에서 빼므로 영향 범위를 알린 뒤 실행한다.

## displayType 참고

| 해상도 | displayType |
| --- | --- |
| 1320x2868 | `APP_IPHONE_69` |
| 1290x2796 | `APP_IPHONE_67` |
| 1284x2778 | `APP_IPHONE_65` |
| 1242x2688 | `APP_IPHONE_65` |
| 2064x2752 | `APP_IPAD_PRO_3GEN_129` |
| 2048x2732 | `APP_IPAD_PRO_129` |

업로드 전 실제 PNG 해상도를 확인해 displayType과 맞는지 검수한다.

## 참고 (온톨로지)

- App Store 도구 전체 목록: [`docs/domain/tool-catalog.md`](../../docs/domain/tool-catalog.md)
- 인증·ASC JWT 모델: [`docs/domain/auth-credentials.md`](../../docs/domain/auth-credentials.md)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.