@yoonion/mimi-seed-mcp 0.3.31 → 0.3.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +219 -219
- package/dist/ai/review.js +1 -1
- package/dist/appstore/errors.js +2 -0
- package/dist/appstore/tools.d.ts +18 -0
- package/dist/appstore/tools.js +56 -1
- package/dist/prompts.js +1 -1
- package/dist/registers/ai.js +1 -1
- package/dist/registers/appstore.js +25 -0
- package/dist/resources.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
# @yoonion/mimi-seed-mcp
|
|
2
|
-
|
|
1
|
+
# @yoonion/mimi-seed-mcp
|
|
2
|
+
|
|
3
3
|
**Mimi Seed** — Firebase · AdMob · Google Play · App Store Connect를 AI 콘솔에서 관리. Claude Code / Codex / Cursor / 기타 MCP 클라이언트에서 한 줄 등록으로 사용.
|
|
4
|
-
|
|
5
|
-
> 이 패키지는 Mimi Seed의 **로컬 MCP 서버**만 포함합니다. 웹 콘솔(Next.js 앱)은 <https://mimi-seed.pryzm.gg/tool>.
|
|
6
|
-
|
|
7
|
-
## 설치
|
|
8
|
-
|
|
4
|
+
|
|
5
|
+
> 이 패키지는 Mimi Seed의 **로컬 MCP 서버**만 포함합니다. 웹 콘솔(Next.js 앱)은 <https://mimi-seed.pryzm.gg/tool>.
|
|
6
|
+
|
|
7
|
+
## 설치
|
|
8
|
+
|
|
9
9
|
Claude Code:
|
|
10
10
|
|
|
11
11
|
```bash
|
|
@@ -20,216 +20,216 @@ command = "npx"
|
|
|
20
20
|
args = ["-y", "@yoonion/mimi-seed-mcp"]
|
|
21
21
|
enabled = true
|
|
22
22
|
```
|
|
23
|
-
|
|
24
|
-
Claude Desktop (`claude_desktop_config.json`):
|
|
25
|
-
|
|
26
|
-
```json
|
|
27
|
-
{
|
|
28
|
-
"mcpServers": {
|
|
29
|
-
"mimi-seed": {
|
|
30
|
-
"command": "npx",
|
|
31
|
-
"args": ["-y", "@yoonion/mimi-seed-mcp"]
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## 첫 사용 전 인증
|
|
38
|
-
|
|
39
|
-
```bash
|
|
40
|
-
npx -y @yoonion/mimi-seed-mcp mimi-seed-auth
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
브라우저가 열리면 Google 계정으로 로그인. 토큰은 `~/.mimi-seed/tokens.json`에 저장되고 자동 갱신됨.
|
|
44
|
-
|
|
45
|
-
플랫폼별 추가 인증 (필요한 것만):
|
|
46
|
-
|
|
47
|
-
```bash
|
|
48
|
-
npx -y @yoonion/mimi-seed-mcp mimi-seed-appstore-auth # App Store Connect (API Key)
|
|
49
|
-
npx -y @yoonion/mimi-seed-mcp mimi-seed-playstore-auth # Google Play 서비스 계정 JSON
|
|
50
|
-
npx -y @yoonion/mimi-seed-mcp mimi-seed-bigquery-auth # BigQuery (Crashlytics export 등)
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
- **App Store Connect**: Users and Access → Keys에서 API Key 생성 후 Issuer ID / Key ID / .p8 경로 입력 → `~/.mimi-seed/appstore.json`
|
|
54
|
-
- **Google Play**: Play Console 서비스 계정 JSON 경로 입력 (패키지별 등록)
|
|
55
|
-
- **BigQuery**: Google OAuth 또는 서비스 계정으로 데이터셋 조회 권한 부여
|
|
56
|
-
|
|
57
|
-
AI 기능(릴리즈 노트 생성, 리뷰 답변)을 쓰려면:
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
export ANTHROPIC_API_KEY=sk-ant-...
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
---
|
|
64
|
-
|
|
65
|
-
## 제공 도구 (110+개)
|
|
66
|
-
|
|
67
|
-
| 영역 | 도구 수 | 주요 도구 |
|
|
68
|
-
|------|---------|-----------|
|
|
69
|
-
| App Store Connect | 30 | `appstore_submit_for_review` / `appstore_upload_screenshot` / `appstore_update_whats_new` / `appstore_create_version` |
|
|
70
|
-
| Google Play | 26 | `playstore_submit_release` / `playstore_promote_release` / `playstore_replace_images` / `playstore_reply_review` / `playstore_verify_service_account` |
|
|
71
|
-
| Firebase | 17 | `firebase_create_android_app` / `firebase_get_android_config` / `firebase_create_ios_app` / `firebase_enable_service` |
|
|
72
|
-
| AdMob | 7 | `admob_list_apps` / `admob_create_ad_unit` / `admob_get_today_earnings` / `admob_get_report` |
|
|
73
|
-
| CI/CD (GitHub Actions · GitLab) | 6 | `ci_trigger_build` / `ci_get_build_status` / `ci_list_workflows` / `ci_cancel_build` |
|
|
74
|
-
| Facebook | 6 | `facebook_post_photo` / `facebook_post_multi_photo` / `facebook_list_pages` |
|
|
75
|
-
| Google Cloud IAM | 5 | `iam_create_service_account` / `iam_create_key` / `iam_add_iam_policy_binding` |
|
|
76
|
-
| BigQuery | 5 | `bigquery_run_query` / `bigquery_list_datasets` / `bigquery_get_table_schema` |
|
|
77
|
-
| 점검 / 위험 | 4 | `playstore_check_submission_risks` / `appstore_check_submission_risks` / `screenshot_validate` / `release_status` |
|
|
78
|
-
| Instagram | 4 | `instagram_post_image` / `instagram_post_carousel` / `instagram_save_config` |
|
|
79
|
-
| AI (Claude) | 2 | `generate_release_notes_from_commits` / `generate_review_reply` |
|
|
80
|
-
| 인증 | 2 | `mimi_seed_auth_start` / `mimi_seed_auth_status` |
|
|
81
|
-
|
|
82
|
-
> 인앱 결제(IAP·구독) 도구는 위 Play Store·App Store 카운트에 포함됩니다 — `playstore_create_subscription` · `appstore_create_inapp_purchase` 등 (`@onesub/providers` 위임).
|
|
83
|
-
|
|
84
|
-
---
|
|
85
|
-
|
|
86
|
-
## 슬래시 커맨드 (MCP Prompts)
|
|
87
|
-
|
|
23
|
+
|
|
24
|
+
Claude Desktop (`claude_desktop_config.json`):
|
|
25
|
+
|
|
26
|
+
```json
|
|
27
|
+
{
|
|
28
|
+
"mcpServers": {
|
|
29
|
+
"mimi-seed": {
|
|
30
|
+
"command": "npx",
|
|
31
|
+
"args": ["-y", "@yoonion/mimi-seed-mcp"]
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 첫 사용 전 인증
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npx -y @yoonion/mimi-seed-mcp mimi-seed-auth
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
브라우저가 열리면 Google 계정으로 로그인. 토큰은 `~/.mimi-seed/tokens.json`에 저장되고 자동 갱신됨.
|
|
44
|
+
|
|
45
|
+
플랫폼별 추가 인증 (필요한 것만):
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npx -y @yoonion/mimi-seed-mcp mimi-seed-appstore-auth # App Store Connect (API Key)
|
|
49
|
+
npx -y @yoonion/mimi-seed-mcp mimi-seed-playstore-auth # Google Play 서비스 계정 JSON
|
|
50
|
+
npx -y @yoonion/mimi-seed-mcp mimi-seed-bigquery-auth # BigQuery (Crashlytics export 등)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- **App Store Connect**: Users and Access → Keys에서 API Key 생성 후 Issuer ID / Key ID / .p8 경로 입력 → `~/.mimi-seed/appstore.json`
|
|
54
|
+
- **Google Play**: Play Console 서비스 계정 JSON 경로 입력 (패키지별 등록)
|
|
55
|
+
- **BigQuery**: Google OAuth 또는 서비스 계정으로 데이터셋 조회 권한 부여
|
|
56
|
+
|
|
57
|
+
AI 기능(릴리즈 노트 생성, 리뷰 답변)을 쓰려면:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
export ANTHROPIC_API_KEY=sk-ant-...
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## 제공 도구 (110+개)
|
|
66
|
+
|
|
67
|
+
| 영역 | 도구 수 | 주요 도구 |
|
|
68
|
+
|------|---------|-----------|
|
|
69
|
+
| App Store Connect | 30 | `appstore_submit_for_review` / `appstore_upload_screenshot` / `appstore_update_whats_new` / `appstore_create_version` |
|
|
70
|
+
| Google Play | 26 | `playstore_submit_release` / `playstore_promote_release` / `playstore_replace_images` / `playstore_reply_review` / `playstore_verify_service_account` |
|
|
71
|
+
| Firebase | 17 | `firebase_create_android_app` / `firebase_get_android_config` / `firebase_create_ios_app` / `firebase_enable_service` |
|
|
72
|
+
| AdMob | 7 | `admob_list_apps` / `admob_create_ad_unit` / `admob_get_today_earnings` / `admob_get_report` |
|
|
73
|
+
| CI/CD (GitHub Actions · GitLab) | 6 | `ci_trigger_build` / `ci_get_build_status` / `ci_list_workflows` / `ci_cancel_build` |
|
|
74
|
+
| Facebook | 6 | `facebook_post_photo` / `facebook_post_multi_photo` / `facebook_list_pages` |
|
|
75
|
+
| Google Cloud IAM | 5 | `iam_create_service_account` / `iam_create_key` / `iam_add_iam_policy_binding` |
|
|
76
|
+
| BigQuery | 5 | `bigquery_run_query` / `bigquery_list_datasets` / `bigquery_get_table_schema` |
|
|
77
|
+
| 점검 / 위험 | 4 | `playstore_check_submission_risks` / `appstore_check_submission_risks` / `screenshot_validate` / `release_status` |
|
|
78
|
+
| Instagram | 4 | `instagram_post_image` / `instagram_post_carousel` / `instagram_save_config` |
|
|
79
|
+
| AI (Claude) | 2 | `generate_release_notes_from_commits` / `generate_review_reply` |
|
|
80
|
+
| 인증 | 2 | `mimi_seed_auth_start` / `mimi_seed_auth_status` |
|
|
81
|
+
|
|
82
|
+
> 인앱 결제(IAP·구독) 도구는 위 Play Store·App Store 카운트에 포함됩니다 — `playstore_create_subscription` · `appstore_create_inapp_purchase` 등 (`@onesub/providers` 위임).
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## 슬래시 커맨드 (MCP Prompts)
|
|
87
|
+
|
|
88
88
|
MCP 클라이언트(Claude Code, Codex 등)에서 슬래시 커맨드로 바로 노출됩니다.
|
|
89
|
-
|
|
90
|
-
| 커맨드 | 설명 |
|
|
91
|
-
|--------|------|
|
|
92
|
-
| `/mimi-seed:deploy` | 블로커 점검 → 릴리즈 노트 생성 → 스토어 적용을 한 번에 |
|
|
93
|
-
| `/mimi-seed:health` | 인증 상태 + 앱 출시 준비도 빠른 요약 |
|
|
94
|
-
| `/mimi-seed:review-inbox` | 미답변 리뷰 조회 → AI 답변 초안 생성 |
|
|
95
|
-
|
|
96
|
-
## MCP Resources
|
|
97
|
-
|
|
98
|
-
| URI | 설명 |
|
|
99
|
-
|-----|------|
|
|
100
|
-
| `mimi-seed://auth/status` | Google OAuth 토큰 상태 (JSON) |
|
|
101
|
-
| `mimi-seed://agent/guide` | 에이전트 역할 정의 — 출시 워크플로우·주의사항 (Markdown) |
|
|
102
|
-
|
|
103
|
-
---
|
|
104
|
-
|
|
105
|
-
## 주요 기능
|
|
106
|
-
|
|
107
|
-
### 제출 위험 점검
|
|
108
|
-
|
|
109
|
-
출시 전 블로커와 경고를 자동으로 점검합니다.
|
|
110
|
-
|
|
111
|
-
```
|
|
112
|
-
"내 앱 출시 전 위험 요소 확인해줘"
|
|
113
|
-
→ playstore_check_submission_risks("com.example.myapp")
|
|
114
|
-
→ appstore_check_submission_risks("1234567890")
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
**점검 항목:**
|
|
118
|
-
- Google Play: 리스팅 완성도(제목/설명/짧은설명), 스크린샷 수, 아이콘, 내부 빌드 존재, 연락처
|
|
119
|
-
- App Store: What's New, 설명/키워드, 스크린샷 커버리지, TestFlight 빌드, 개인정보처리방침 URL
|
|
120
|
-
|
|
121
|
-
---
|
|
122
|
-
|
|
123
|
-
### 스크린샷 해상도 검증
|
|
124
|
-
|
|
125
|
-
업로드 전 로컬 파일을 스토어 규격과 비교합니다.
|
|
126
|
-
|
|
127
|
-
```
|
|
128
|
-
"이 스크린샷들이 App Store 규격에 맞는지 확인해줘"
|
|
129
|
-
→ screenshot_validate(["/path/to/screen1.png", "/path/to/screen2.png"], platform="ios", displayType="APP_IPHONE_69")
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
iOS displayType 예시: `APP_IPHONE_69`, `APP_IPHONE_67`, `APP_IPHONE_65`, `APP_IPAD_PRO_3GEN_129`
|
|
133
|
-
Android imageType 예시: `phoneScreenshots`, `sevenInchScreenshots`, `featureGraphic`
|
|
134
|
-
|
|
135
|
-
---
|
|
136
|
-
|
|
137
|
-
### AI 릴리즈 노트 생성 (ANTHROPIC_API_KEY 필요)
|
|
138
|
-
|
|
139
|
-
git 커밋 내역을 Claude가 사용자 친화적인 릴리즈 노트로 변환합니다.
|
|
140
|
-
|
|
141
|
-
```
|
|
142
|
-
"최근 커밋으로 릴리즈 노트 만들어줘"
|
|
143
|
-
→ generate_release_notes_from_commits(
|
|
144
|
-
commits=[{message: "feat: 다크모드 추가"}, ...],
|
|
145
|
-
appName="MyApp",
|
|
146
|
-
locales=["ko", "en-US", "ja"]
|
|
147
|
-
)
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
3가지 톤(간결/상세/마케팅) + 다국어를 한 번에 생성. 이후 `playstore_update_release_notes` 또는 `appstore_update_whats_new`로 바로 적용.
|
|
151
|
-
|
|
152
|
-
---
|
|
153
|
-
|
|
154
|
-
### AI 리뷰 답변 생성 (ANTHROPIC_API_KEY 필요)
|
|
155
|
-
|
|
156
|
-
스토어 리뷰에 대한 AI 답변 초안을 생성합니다.
|
|
157
|
-
|
|
158
|
-
```
|
|
159
|
-
"이 리뷰에 답변 작성해줘"
|
|
160
|
-
→ generate_review_reply(
|
|
161
|
-
reviewText="앱이 자꾸 튕겨요",
|
|
162
|
-
rating=2,
|
|
163
|
-
appName="MyApp",
|
|
164
|
-
tone="empathetic",
|
|
165
|
-
language="ko"
|
|
166
|
-
)
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
tone 옵션: `friendly`(친근) / `professional`(정중) / `empathetic`(공감) / `brief`(간결)
|
|
170
|
-
|
|
171
|
-
> ⚠ AI 생성 답변은 초안입니다. 게시 전 반드시 검토하세요.
|
|
172
|
-
> 답변 게시는 `
|
|
173
|
-
|
|
174
|
-
---
|
|
175
|
-
|
|
176
|
-
## End-to-end: 서비스 계정 → JSON 키 → Play Console 권한
|
|
177
|
-
|
|
178
|
-
서버(예: [onesub](https://github.com/jeonghwanko/onesub))가 Google Play 영수증을 백그라운드로 검증하려면 서비스 계정 JSON이 필요합니다. Claude에게 한 번에 시킬 수 있어요:
|
|
179
|
-
|
|
180
|
-
> 1. `my-project`에 `onesub-play-verifier` 서비스 계정 만들고
|
|
181
|
-
> 2. JSON 키 발급받아서
|
|
182
|
-
> 3. `com.yourapp.id`에 대해 검증
|
|
183
|
-
|
|
184
|
-
Claude가 연쇄 호출:
|
|
185
|
-
|
|
186
|
-
- `iam_create_service_account("my-project", "onesub-play-verifier", "onesub Play verifier")`
|
|
187
|
-
- `iam_create_key("onesub-play-verifier@my-project.iam.gserviceaccount.com")` → JSON 반환
|
|
188
|
-
- `playstore_verify_service_account(<json>, "com.yourapp.id")` → 아직 Play Console 권한이 없어서 403 반환 기대
|
|
189
|
-
|
|
190
|
-
그 다음 **Play Console에서 수동으로** (또는 별도 androidpublisher.users API 호출):
|
|
191
|
-
|
|
192
|
-
- Users and permissions → 서비스 계정 이메일 초대
|
|
193
|
-
- **View financial data, orders, and cancellation survey responses** 체크
|
|
194
|
-
- **~5분 대기** 후 `playstore_verify_service_account` 재실행 → ✓
|
|
195
|
-
|
|
196
|
-
마지막으로 JSON을 `GOOGLE_SERVICE_ACCOUNT_KEY` 서버 env에 넣으면 Play 영수증 검증 가능.
|
|
197
|
-
|
|
198
|
-
> Cloud IAM 역할과 Play Console 권한은 다릅니다. `iam_add_iam_policy_binding`은 Cloud IAM 역할(예: `roles/iam.serviceAccountTokenCreator`)만 부여 — Play Console의 "View financial data"는 별도.
|
|
199
|
-
|
|
200
|
-
---
|
|
201
|
-
|
|
202
|
-
## 환경변수
|
|
203
|
-
|
|
204
|
-
| 변수 | 설명 |
|
|
205
|
-
|------|------|
|
|
206
|
-
| `ANTHROPIC_API_KEY` | AI 릴리즈 노트 생성 / 리뷰 답변 활성화 (선택) |
|
|
207
|
-
|
|
208
|
-
---
|
|
209
|
-
|
|
210
|
-
## 레거시 호환성
|
|
211
|
-
|
|
212
|
-
Preseed 시절(`~/.preseed/`) 데이터는 자동으로 이어받음:
|
|
213
|
-
|
|
214
|
-
- `~/.preseed/tokens.json` 있으면 읽음 (재인증 불필요)
|
|
215
|
-
- `~/.preseed/appstore.json`도 동일
|
|
216
|
-
- 환경변수 `PRESEED_GOOGLE_CLIENT_ID` / `PRESEED_GOOGLE_CLIENT_SECRET` 계속 인식
|
|
217
|
-
|
|
218
|
-
새로 쓰는 건 `~/.mimi-seed/`.
|
|
219
|
-
|
|
220
|
-
---
|
|
221
|
-
|
|
222
|
-
## Links
|
|
223
|
-
|
|
224
|
-
- CLI 패키지: [`mimi-seed`](https://www.npmjs.com/package/mimi-seed)
|
|
225
|
-
- 웹 콘솔: <https://mimi-seed.pryzm.gg/tool>
|
|
226
|
-
- 저장소: <https://github.com/jeonghwanko/mimi-seed>
|
|
227
|
-
|
|
228
|
-
---
|
|
229
|
-
|
|
230
|
-
## License
|
|
231
|
-
|
|
232
|
-
[PolyForm Noncommercial License 1.0.0](../../LICENSE) — 비상업적 사용만 허용.
|
|
233
|
-
상업적 이용 문의: turbo08@gmail.com
|
|
234
|
-
|
|
235
|
-
**Required Notice:** Copyright 2026 Pryzm GG (https://mimi-seed.pryzm.gg)
|
|
89
|
+
|
|
90
|
+
| 커맨드 | 설명 |
|
|
91
|
+
|--------|------|
|
|
92
|
+
| `/mimi-seed:deploy` | 블로커 점검 → 릴리즈 노트 생성 → 스토어 적용을 한 번에 |
|
|
93
|
+
| `/mimi-seed:health` | 인증 상태 + 앱 출시 준비도 빠른 요약 |
|
|
94
|
+
| `/mimi-seed:review-inbox` | 미답변 리뷰 조회 → AI 답변 초안 생성 |
|
|
95
|
+
|
|
96
|
+
## MCP Resources
|
|
97
|
+
|
|
98
|
+
| URI | 설명 |
|
|
99
|
+
|-----|------|
|
|
100
|
+
| `mimi-seed://auth/status` | Google OAuth 토큰 상태 (JSON) |
|
|
101
|
+
| `mimi-seed://agent/guide` | 에이전트 역할 정의 — 출시 워크플로우·주의사항 (Markdown) |
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## 주요 기능
|
|
106
|
+
|
|
107
|
+
### 제출 위험 점검
|
|
108
|
+
|
|
109
|
+
출시 전 블로커와 경고를 자동으로 점검합니다.
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
"내 앱 출시 전 위험 요소 확인해줘"
|
|
113
|
+
→ playstore_check_submission_risks("com.example.myapp")
|
|
114
|
+
→ appstore_check_submission_risks("1234567890")
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**점검 항목:**
|
|
118
|
+
- Google Play: 리스팅 완성도(제목/설명/짧은설명), 스크린샷 수, 아이콘, 내부 빌드 존재, 연락처
|
|
119
|
+
- App Store: What's New, 설명/키워드, 스크린샷 커버리지, TestFlight 빌드, 개인정보처리방침 URL
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
### 스크린샷 해상도 검증
|
|
124
|
+
|
|
125
|
+
업로드 전 로컬 파일을 스토어 규격과 비교합니다.
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
"이 스크린샷들이 App Store 규격에 맞는지 확인해줘"
|
|
129
|
+
→ screenshot_validate(["/path/to/screen1.png", "/path/to/screen2.png"], platform="ios", displayType="APP_IPHONE_69")
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
iOS displayType 예시: `APP_IPHONE_69`, `APP_IPHONE_67`, `APP_IPHONE_65`, `APP_IPAD_PRO_3GEN_129`
|
|
133
|
+
Android imageType 예시: `phoneScreenshots`, `sevenInchScreenshots`, `featureGraphic`
|
|
134
|
+
|
|
135
|
+
---
|
|
136
|
+
|
|
137
|
+
### AI 릴리즈 노트 생성 (ANTHROPIC_API_KEY 필요)
|
|
138
|
+
|
|
139
|
+
git 커밋 내역을 Claude가 사용자 친화적인 릴리즈 노트로 변환합니다.
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
"최근 커밋으로 릴리즈 노트 만들어줘"
|
|
143
|
+
→ generate_release_notes_from_commits(
|
|
144
|
+
commits=[{message: "feat: 다크모드 추가"}, ...],
|
|
145
|
+
appName="MyApp",
|
|
146
|
+
locales=["ko", "en-US", "ja"]
|
|
147
|
+
)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
3가지 톤(간결/상세/마케팅) + 다국어를 한 번에 생성. 이후 `playstore_update_release_notes` 또는 `appstore_update_whats_new`로 바로 적용.
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
### AI 리뷰 답변 생성 (ANTHROPIC_API_KEY 필요)
|
|
155
|
+
|
|
156
|
+
스토어 리뷰에 대한 AI 답변 초안을 생성합니다.
|
|
157
|
+
|
|
158
|
+
```
|
|
159
|
+
"이 리뷰에 답변 작성해줘"
|
|
160
|
+
→ generate_review_reply(
|
|
161
|
+
reviewText="앱이 자꾸 튕겨요",
|
|
162
|
+
rating=2,
|
|
163
|
+
appName="MyApp",
|
|
164
|
+
tone="empathetic",
|
|
165
|
+
language="ko"
|
|
166
|
+
)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
tone 옵션: `friendly`(친근) / `professional`(정중) / `empathetic`(공감) / `brief`(간결)
|
|
170
|
+
|
|
171
|
+
> ⚠ AI 생성 답변은 초안입니다. 게시 전 반드시 검토하세요.
|
|
172
|
+
> 답변 게시는 `playstore_reply_review` 도구를 사용하세요.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## End-to-end: 서비스 계정 → JSON 키 → Play Console 권한
|
|
177
|
+
|
|
178
|
+
서버(예: [onesub](https://github.com/jeonghwanko/onesub))가 Google Play 영수증을 백그라운드로 검증하려면 서비스 계정 JSON이 필요합니다. Claude에게 한 번에 시킬 수 있어요:
|
|
179
|
+
|
|
180
|
+
> 1. `my-project`에 `onesub-play-verifier` 서비스 계정 만들고
|
|
181
|
+
> 2. JSON 키 발급받아서
|
|
182
|
+
> 3. `com.yourapp.id`에 대해 검증
|
|
183
|
+
|
|
184
|
+
Claude가 연쇄 호출:
|
|
185
|
+
|
|
186
|
+
- `iam_create_service_account("my-project", "onesub-play-verifier", "onesub Play verifier")`
|
|
187
|
+
- `iam_create_key("onesub-play-verifier@my-project.iam.gserviceaccount.com")` → JSON 반환
|
|
188
|
+
- `playstore_verify_service_account(<json>, "com.yourapp.id")` → 아직 Play Console 권한이 없어서 403 반환 기대
|
|
189
|
+
|
|
190
|
+
그 다음 **Play Console에서 수동으로** (또는 별도 androidpublisher.users API 호출):
|
|
191
|
+
|
|
192
|
+
- Users and permissions → 서비스 계정 이메일 초대
|
|
193
|
+
- **View financial data, orders, and cancellation survey responses** 체크
|
|
194
|
+
- **~5분 대기** 후 `playstore_verify_service_account` 재실행 → ✓
|
|
195
|
+
|
|
196
|
+
마지막으로 JSON을 `GOOGLE_SERVICE_ACCOUNT_KEY` 서버 env에 넣으면 Play 영수증 검증 가능.
|
|
197
|
+
|
|
198
|
+
> Cloud IAM 역할과 Play Console 권한은 다릅니다. `iam_add_iam_policy_binding`은 Cloud IAM 역할(예: `roles/iam.serviceAccountTokenCreator`)만 부여 — Play Console의 "View financial data"는 별도.
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## 환경변수
|
|
203
|
+
|
|
204
|
+
| 변수 | 설명 |
|
|
205
|
+
|------|------|
|
|
206
|
+
| `ANTHROPIC_API_KEY` | AI 릴리즈 노트 생성 / 리뷰 답변 활성화 (선택) |
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
## 레거시 호환성
|
|
211
|
+
|
|
212
|
+
Preseed 시절(`~/.preseed/`) 데이터는 자동으로 이어받음:
|
|
213
|
+
|
|
214
|
+
- `~/.preseed/tokens.json` 있으면 읽음 (재인증 불필요)
|
|
215
|
+
- `~/.preseed/appstore.json`도 동일
|
|
216
|
+
- 환경변수 `PRESEED_GOOGLE_CLIENT_ID` / `PRESEED_GOOGLE_CLIENT_SECRET` 계속 인식
|
|
217
|
+
|
|
218
|
+
새로 쓰는 건 `~/.mimi-seed/`.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## Links
|
|
223
|
+
|
|
224
|
+
- CLI 패키지: [`mimi-seed`](https://www.npmjs.com/package/mimi-seed)
|
|
225
|
+
- 웹 콘솔: <https://mimi-seed.pryzm.gg/tool>
|
|
226
|
+
- 저장소: <https://github.com/jeonghwanko/mimi-seed>
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## License
|
|
231
|
+
|
|
232
|
+
[PolyForm Noncommercial License 1.0.0](../../LICENSE) — 비상업적 사용만 허용.
|
|
233
|
+
상업적 이용 문의: turbo08@gmail.com
|
|
234
|
+
|
|
235
|
+
**Required Notice:** Copyright 2026 Pryzm GG (https://mimi-seed.pryzm.gg)
|
package/dist/ai/review.js
CHANGED
package/dist/appstore/errors.js
CHANGED
|
@@ -27,6 +27,8 @@ const CODE_HINTS = {
|
|
|
27
27
|
FORBIDDEN_ERROR: 'API Key 권한 부족 — App Store Connect > Users and Access 에서 키 role 확인.',
|
|
28
28
|
// submit 직후 cancel 시도 (큐 진입 후)
|
|
29
29
|
STATE_ERROR: '현재 상태에서 허용되지 않는 작업. cancel_review 라면 큐 진입 후라서 불가 — 새 versionString 으로 우회.',
|
|
30
|
+
// JWT 거부 — 잘못된 자격증명
|
|
31
|
+
NOT_AUTHORIZED: 'API 키가 거부됐어요 — issuerId/keyId/.p8 조합 불일치 가능. appstore_verify_credentials 로 진단하고 mimi-seed auth appstore 로 재등록.',
|
|
30
32
|
};
|
|
31
33
|
/** Apple 표준 에러 응답 파싱 시도. 실패하면 null 반환. */
|
|
32
34
|
function parseAppleErrorBody(body) {
|
package/dist/appstore/tools.d.ts
CHANGED
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
export declare function apiGet(path: string, params?: Record<string, string>): Promise<any>;
|
|
2
|
+
export interface AppStoreVerifyResult {
|
|
3
|
+
ok: boolean;
|
|
4
|
+
stage: 'creds' | 'sign' | 'auth' | 'api' | 'done';
|
|
5
|
+
message: string;
|
|
6
|
+
httpStatus?: number;
|
|
7
|
+
appCount?: number;
|
|
8
|
+
firstApp?: {
|
|
9
|
+
id: string;
|
|
10
|
+
name?: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* appstore.json 자격증명 유효성 단계별 검증 (creds → sign → auth → api).
|
|
15
|
+
* playstore_verify_service_account 의 App Store 대응. 읽기 전용 — GET /apps?limit=1.
|
|
16
|
+
* 파일 존재만 보는 requireAppStoreCreds 와 달리, 잘못된 .p8/keyId/issuerId 를
|
|
17
|
+
* "첫 호출 401" 로 늦게 터지기 전에 setup 단계에서 잡아준다.
|
|
18
|
+
*/
|
|
19
|
+
export declare function verifyAppStoreCredentials(): Promise<AppStoreVerifyResult>;
|
|
2
20
|
export declare function listApps(): Promise<any>;
|
|
3
21
|
export declare function getApp(appId: string): Promise<any>;
|
|
4
22
|
export declare function listVersions(appId: string): Promise<any>;
|
package/dist/appstore/tools.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getAuthHeaders } from './auth.js';
|
|
1
|
+
import { getAuthHeaders, getAppStoreCredentials, generateToken } from './auth.js';
|
|
2
2
|
import { friendlyAppStoreError } from './errors.js';
|
|
3
3
|
/**
|
|
4
4
|
* App Store Connect API v1 래퍼
|
|
@@ -29,6 +29,61 @@ export async function apiGet(path, params) {
|
|
|
29
29
|
}
|
|
30
30
|
return res.json();
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* appstore.json 자격증명 유효성 단계별 검증 (creds → sign → auth → api).
|
|
34
|
+
* playstore_verify_service_account 의 App Store 대응. 읽기 전용 — GET /apps?limit=1.
|
|
35
|
+
* 파일 존재만 보는 requireAppStoreCreds 와 달리, 잘못된 .p8/keyId/issuerId 를
|
|
36
|
+
* "첫 호출 401" 로 늦게 터지기 전에 setup 단계에서 잡아준다.
|
|
37
|
+
*/
|
|
38
|
+
export async function verifyAppStoreCredentials() {
|
|
39
|
+
const creds = getAppStoreCredentials();
|
|
40
|
+
if (!creds) {
|
|
41
|
+
return {
|
|
42
|
+
ok: false,
|
|
43
|
+
stage: 'creds',
|
|
44
|
+
message: '~/.mimi-seed/appstore.json 이 없습니다. `mimi-seed auth appstore` 로 등록하세요.',
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
let token;
|
|
48
|
+
try {
|
|
49
|
+
token = await generateToken(creds);
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
return {
|
|
53
|
+
ok: false,
|
|
54
|
+
stage: 'sign',
|
|
55
|
+
message: `JWT 서명 실패 — .p8 privateKey / keyId 확인 필요.\n${e.message}`,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
let res;
|
|
59
|
+
try {
|
|
60
|
+
res = await fetch(`${BASE}/apps?limit=1`, { headers: { Authorization: `Bearer ${token}` } });
|
|
61
|
+
}
|
|
62
|
+
catch (e) {
|
|
63
|
+
return { ok: false, stage: 'api', message: `App Store API 연결 실패: ${e.message}` };
|
|
64
|
+
}
|
|
65
|
+
if (res.status === 401 || res.status === 403) {
|
|
66
|
+
return {
|
|
67
|
+
ok: false,
|
|
68
|
+
stage: 'auth',
|
|
69
|
+
httpStatus: res.status,
|
|
70
|
+
message: 'Apple이 인증을 거부했어요 — issuerId / keyId / .p8 조합이 틀렸거나 키 권한이 부족합니다.\n`mimi-seed auth appstore` 로 재등록하세요.',
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (!res.ok) {
|
|
74
|
+
const body = await res.text();
|
|
75
|
+
return { ok: false, stage: 'api', httpStatus: res.status, message: `App Store API ${res.status}: ${body.slice(0, 200)}` };
|
|
76
|
+
}
|
|
77
|
+
const data = (await res.json());
|
|
78
|
+
const first = data.data?.[0];
|
|
79
|
+
return {
|
|
80
|
+
ok: true,
|
|
81
|
+
stage: 'done',
|
|
82
|
+
message: '인증 유효',
|
|
83
|
+
appCount: data.meta?.paging?.total,
|
|
84
|
+
firstApp: first ? { id: first.id, name: first.attributes?.name } : undefined,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
32
87
|
async function apiPatch(path, body) {
|
|
33
88
|
const headers = await getAuthHeaders();
|
|
34
89
|
if (!headers)
|
package/dist/prompts.js
CHANGED
|
@@ -61,7 +61,7 @@ export function registerPrompts(server) {
|
|
|
61
61
|
'3. 각 리뷰에 generate_review_reply 로 답변 초안 생성',
|
|
62
62
|
` 톤: ${tone ?? 'empathetic'}`,
|
|
63
63
|
'4. 초안 보여주고 게시 여부 확인 (비가역 — 반드시 동의 받을 것)',
|
|
64
|
-
'5. 확인 후
|
|
64
|
+
'5. 확인 후 playstore_reply_review 로 게시',
|
|
65
65
|
'',
|
|
66
66
|
'⚠️ AI 생성 답변은 초안입니다. 게시 전 반드시 검토하세요.',
|
|
67
67
|
].join('\n'),
|
package/dist/registers/ai.js
CHANGED
|
@@ -32,7 +32,7 @@ export function registerAiTools(server) {
|
|
|
32
32
|
'tone: friendly(친근) / professional(정중) / empathetic(공감) / brief(간결) — 기본: friendly',
|
|
33
33
|
'language: ko / en / ja / zh 등 — 기본: ko',
|
|
34
34
|
'⚠ 생성된 답변은 초안입니다. 게시 전 반드시 검토하세요.',
|
|
35
|
-
'답변 게시는
|
|
35
|
+
'답변 게시는 playstore_reply_review 도구를 사용하세요.',
|
|
36
36
|
].join(' '), {
|
|
37
37
|
reviewText: z.string().describe('리뷰 원문'),
|
|
38
38
|
rating: z.number().min(1).max(5).optional().describe('별점 (1~5)'),
|
|
@@ -10,6 +10,31 @@ export function registerAppstoreTools(server) {
|
|
|
10
10
|
const apps = await appstore.listApps();
|
|
11
11
|
return { content: [{ type: 'text', text: JSON.stringify(apps, null, 2) }] };
|
|
12
12
|
});
|
|
13
|
+
server.tool('appstore_verify_credentials', 'App Store Connect API 키(appstore.json) 유효성 검증 — JWT 서명 + GET /apps 호출로 creds/sign/auth/api 단계별 진단. 첫 도구 호출에서 401로 늦게 터지기 전에 setup 직후 확인용. 인자 없음.', {}, async () => {
|
|
14
|
+
const r = await appstore.verifyAppStoreCredentials();
|
|
15
|
+
if (r.ok) {
|
|
16
|
+
return {
|
|
17
|
+
content: [{
|
|
18
|
+
type: 'text',
|
|
19
|
+
text: [
|
|
20
|
+
'✓ App Store Connect 인증 유효',
|
|
21
|
+
r.appCount != null ? ` 접근 가능 앱: ${r.appCount}개` : '',
|
|
22
|
+
r.firstApp ? ` 예: ${r.firstApp.name ?? r.firstApp.id}` : '',
|
|
23
|
+
].filter(Boolean).join('\n'),
|
|
24
|
+
}],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
content: [{
|
|
29
|
+
type: 'text',
|
|
30
|
+
text: [
|
|
31
|
+
`✗ 검증 실패 (stage: ${r.stage}${r.httpStatus ? `, HTTP ${r.httpStatus}` : ''})`,
|
|
32
|
+
'',
|
|
33
|
+
r.message,
|
|
34
|
+
].join('\n'),
|
|
35
|
+
}],
|
|
36
|
+
};
|
|
37
|
+
});
|
|
13
38
|
server.tool('appstore_get_app', 'App Store Connect 앱 상세 정보', { appId: z.string().describe('앱 ID (숫자)') }, async ({ appId }) => {
|
|
14
39
|
const app = await appstore.getApp(appId);
|
|
15
40
|
return { content: [{ type: 'text', text: JSON.stringify(app, null, 2) }] };
|
package/dist/resources.js
CHANGED
|
@@ -44,7 +44,7 @@ export function registerResources(server) {
|
|
|
44
44
|
'',
|
|
45
45
|
'- `playstore_submit_release(status=completed)` — 비가역, 반드시 명시 동의 필요',
|
|
46
46
|
'- `appstore_submit_for_review` — 비가역, 반드시 명시 동의 필요',
|
|
47
|
-
'- `
|
|
47
|
+
'- `playstore_reply_review` — 공개 게시, 반드시 검토 후 동의 필요',
|
|
48
48
|
].join('\n'),
|
|
49
49
|
}],
|
|
50
50
|
}));
|
package/package.json
CHANGED