aimakeall-mcp 0.4.0 → 0.4.1

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 CHANGED
@@ -16,7 +16,7 @@ Claude Code·Codex 같은 MCP 클라이언트에서 자연어로 AImakeAll 영
16
16
  "mcpServers": {
17
17
  "aimakeall": {
18
18
  "command": "npx",
19
- "args": ["-y", "aimakeall-mcp@0.4.0"],
19
+ "args": ["-y", "aimakeall-mcp@0.4.1"],
20
20
  "env": { "AIMAKEALL_PAT": "aio_pat_..." }
21
21
  }
22
22
  }
@@ -314,7 +314,7 @@ export function registerCloudTools(server, config, api) {
314
314
 
315
315
  server.tool(
316
316
  "generate_scene_image",
317
- "씬 이미지를 생성합니다 (기획 결과의 imagePrompt 사용). 반환된 imageUrl을 씬 영상 생성의 입력으로 쓰세요. 캐릭터/앞씬 일관성이 필요하면 씬의 imageUrl을 referenceImageUrls로 전달하세요.",
317
+ "씬 이미지를 생성합니다 (기획 결과의 imagePrompt 사용). 반환된 imageUrl을 씬 영상 생성의 입력으로 쓰세요. 인물·제품 일관성은 참조 방식이 권장 경로입니다: 첫 씬(또는 캐릭터 시트/제품 사진)의 이미지를 referenceImageUrls·referenceImagePaths모든 씬에 앵커로 전달하세요.",
318
318
  {
319
319
  prompt: z.string().describe("이미지 프롬프트 (plan 결과의 imagePrompt)"),
320
320
  aspectRatio: z.string().optional().describe("기본 9:16"),
@@ -1101,196 +1101,6 @@ export function registerCloudTools(server, config, api) {
1101
1101
  }),
1102
1102
  );
1103
1103
 
1104
- // ── 인플루언서(소울) 스튜디오 ────────────────────────────────────────────────
1105
- server.tool(
1106
- "create_influencer_character",
1107
- "참조 사진으로 인플루언서(소울) 캐릭터를 학습 등록합니다. 학습 비용 $2.50(1회성) — 실패 시 자동 재시도 금지(중복 과금). 등록 후 influencer_character_status로 completed까지 10초 간격 폴링하세요 (수 분 소요).",
1108
- {
1109
- name: z.string().min(1).describe("캐릭터 이름"),
1110
- photoPaths: z.array(z.string()).min(5).max(18).describe("동일 인물 사진 로컬 경로 5~18장 (jpg/png/webp)"),
1111
- },
1112
- wrapCloudHandler(config, async ({ name, photoPaths }) => {
1113
- for (const filePath of photoPaths) assertAllowedInputFile(filePath, ALLOWED_IMAGE_EXTS, { kind: "참조 사진" });
1114
- const publicUrls = [];
1115
- // 업로드 URL 발급은 사진 수만큼 쓰기 슬롯(20/분)을 쓰므로, 분당 한도에 걸리면
1116
- // retryAfterSeconds 만큼 대기 후 이어서 진행한다(발급된 URL 은 보존).
1117
- const issueUploadUrl = async (mime) => {
1118
- for (let attempt = 0; ; attempt += 1) {
1119
- try {
1120
- return await api.request("/api/tracker/higgsfield/files/generate-upload-url", {
1121
- body: { content_type: mime },
1122
- method: "POST",
1123
- timeoutMs: 30_000,
1124
- });
1125
- } catch (error) {
1126
- if (error instanceof AimakeallApiError && error.errorCode === "MACHINE_RATE_LIMITED" && attempt < 3) {
1127
- await new Promise((resolve) => setTimeout(resolve, Math.max(1, error.retryAfterSeconds || 10) * 1000));
1128
- continue;
1129
- }
1130
- throw error;
1131
- }
1132
- }
1133
- };
1134
- // presigned PUT(직접) — 컴패니언 불필요.
1135
- for (const filePath of photoPaths) {
1136
- const mime = guessMimeType(filePath, "image/jpeg");
1137
- const issued = await issueUploadUrl(mime);
1138
- const uploadUrl = String(issued?.upload_url || "");
1139
- const publicUrl = String(issued?.public_url || "");
1140
- if (!uploadUrl || !publicUrl) {
1141
- return textResult("업로드 URL 발급에 실패했습니다. Higgsfield API 키 연결을 확인하세요.", { isError: true });
1142
- }
1143
- const put = await fetch(uploadUrl, {
1144
- body: readFileSync(filePath),
1145
- headers: { "Content-Type": mime },
1146
- method: "PUT",
1147
- signal: AbortSignal.timeout(120_000),
1148
- });
1149
- if (!put.ok) {
1150
- return textResult(`사진 업로드 실패 (HTTP ${put.status}): ${path.basename(filePath)}`, { isError: true });
1151
- }
1152
- publicUrls.push(publicUrl);
1153
- }
1154
- let payload;
1155
- try {
1156
- // 서버의 업스트림 창(90s)보다 길게 잡아, 클라이언트가 먼저 끊어 "성공했는데
1157
- // 실패로 오인 → 재시도 → 중복 과금($2.50)" 되는 상황을 방지한다.
1158
- payload = await api.request("/api/tracker/higgsfield/v1/custom-references", {
1159
- body: { input_images: publicUrls.map((url) => ({ image_url: url, type: "image_url" })), name },
1160
- method: "POST",
1161
- timeoutMs: 120_000,
1162
- });
1163
- } catch (error) {
1164
- const reason = String(error?.message || error);
1165
- return textResult(
1166
- `캐릭터 학습 등록 요청이 실패했습니다: ${reason}\n재시도 전에 반드시 list_influencer_characters로 캐릭터가 이미 생성됐는지 확인하세요 — 생성돼 있다면 재시도는 중복 과금($2.50)입니다.`,
1167
- { isError: true },
1168
- );
1169
- }
1170
- const referenceId = String(payload?.id || payload?.reference_id || "");
1171
- if (!referenceId) return textResult("캐릭터 학습 등록 응답에 ID가 없습니다. list_influencer_characters로 생성 여부를 확인하세요.", { isError: true });
1172
- return jsonResult({
1173
- costUsd: payload?.costUsd,
1174
- next: "influencer_character_status를 10초 간격으로 폴링해 completed를 기다리세요. 이 호출을 재시도하면 중복 과금됩니다.",
1175
- photoCount: publicUrls.length,
1176
- referenceId,
1177
- status: payload?.status,
1178
- });
1179
- }),
1180
- );
1181
-
1182
- server.tool(
1183
- "influencer_character_status",
1184
- "소울 캐릭터 학습 상태를 조회합니다 (terminal: completed | failed).",
1185
- { referenceId: z.string().min(1) },
1186
- wrapCloudHandler(config, async ({ referenceId }) => {
1187
- const payload = await api.request(`/api/tracker/higgsfield/v1/custom-references/${encodeURIComponent(referenceId)}`, {
1188
- method: "GET",
1189
- timeoutMs: 30_000,
1190
- });
1191
- return jsonResult({
1192
- name: payload?.name,
1193
- referenceId,
1194
- status: payload?.status,
1195
- thumbnailUrl: payload?.thumbnail_url,
1196
- });
1197
- }),
1198
- );
1199
-
1200
- server.tool(
1201
- "list_influencer_characters",
1202
- "등록된 소울 캐릭터 목록을 조회합니다. (machine 토큰은 서버 경유로 만든 캐릭터만 상세 조회·생성에 사용 가능)",
1203
- { page: z.number().int().min(1).optional().describe("기본 1") },
1204
- wrapCloudHandler(config, async ({ page = 1 }) => {
1205
- const payload = await api.request(`/api/tracker/higgsfield/v1/custom-references/list?page=${page}&page_size=50`, {
1206
- method: "GET",
1207
- timeoutMs: 30_000,
1208
- });
1209
- return jsonResult({
1210
- characters: (Array.isArray(payload?.items) ? payload.items : []).map((item) => ({
1211
- id: item?.id,
1212
- name: item?.name,
1213
- status: item?.status,
1214
- })),
1215
- page,
1216
- totalPages: payload?.total_pages,
1217
- });
1218
- }),
1219
- );
1220
-
1221
- server.tool(
1222
- "suggest_influencer_prompts",
1223
- "소울 이미지용 연출·프롬프트 10종을 추천받습니다. 반환 prompt는 부정규칙까지 완성형이므로 generate_influencer_image에 그대로 쓰세요.",
1224
- {
1225
- gender: z.enum(["여자", "남자"]),
1226
- ageRange: z.enum(["10대", "20대", "30대", "40대", "50대", "60대"]),
1227
- keyword: z.string().min(1).describe("장면 키워드 (예: 카페에서 책 읽는 모습)"),
1228
- },
1229
- wrapCloudHandler(config, async ({ gender, ageRange, keyword }) => {
1230
- const { events } = await api.requestSse("/api/tracker/gemini/soul-prompts", {
1231
- body: { ageRange, gender, imageModel: "soul", keyword },
1232
- timeoutMs: 180_000,
1233
- });
1234
- const items = events
1235
- .filter((event) => event?.type === "item" && event.item)
1236
- .map((event) => ({ directing: event.item.directing, id: event.item.id, prompt: event.item.prompt }));
1237
- if (!items.length) return textResult("프롬프트 추천 결과가 비어 있습니다.", { isError: true });
1238
- return jsonResult({ count: items.length, items });
1239
- }),
1240
- );
1241
-
1242
- server.tool(
1243
- "generate_influencer_image",
1244
- "학습 완료(completed)된 소울 캐릭터로 인플루언서 이미지를 생성합니다 (720p $0.094/장, 1080p $0.19/장). 반환 requestId를 influencer_image_status로 폴링하세요 (~30초).",
1245
- {
1246
- prompt: z.string().min(1).describe("영문 프롬프트 (suggest_influencer_prompts 결과 그대로 권장)"),
1247
- referenceId: z.string().min(1).describe("completed 상태의 캐릭터 referenceId"),
1248
- aspectRatio: z.enum(["9:16", "16:9", "4:3", "3:4", "1:1", "2:3", "3:2"]).optional().describe("기본 4:3"),
1249
- resolution: z.enum(["720p", "1080p"]).optional().describe("기본 720p"),
1250
- imageReferenceUrl: z.string().optional().describe("구도/씬 참조 이미지 URL (선택)"),
1251
- seed: z.number().int().optional().describe("재현용 시드 (선택)"),
1252
- },
1253
- wrapCloudHandler(config, async ({ prompt, referenceId, aspectRatio = "4:3", resolution = "720p", imageReferenceUrl = "", seed }) => {
1254
- const payload = await api.request("/api/tracker/higgsfield/higgsfield-ai/soul/character", {
1255
- body: {
1256
- aspect_ratio: aspectRatio,
1257
- batch_size: 1,
1258
- custom_reference_id: referenceId,
1259
- custom_reference_strength: 1,
1260
- enhance_prompt: false,
1261
- ...(imageReferenceUrl ? { image_reference_url: imageReferenceUrl } : {}),
1262
- prompt,
1263
- resolution,
1264
- ...(seed !== undefined ? { seed } : {}),
1265
- },
1266
- method: "POST",
1267
- timeoutMs: 60_000,
1268
- });
1269
- const requestId = String(payload?.request_id || payload?.id || "");
1270
- if (!requestId) return textResult("이미지 생성 요청 응답에 request_id가 없습니다.", { isError: true });
1271
- return jsonResult({ costUsd: payload?.costUsd, requestId, status: payload?.status });
1272
- }),
1273
- );
1274
-
1275
- server.tool(
1276
- "influencer_image_status",
1277
- "소울 이미지 생성 상태를 조회합니다 (terminal: completed | failed | nsfw | canceled). 결과 이미지는 만료 없는 공개 URL입니다.",
1278
- { requestId: z.string().min(1) },
1279
- wrapCloudHandler(config, async ({ requestId }) => {
1280
- const payload = await api.request(`/api/tracker/higgsfield/requests/${encodeURIComponent(requestId)}/status`, {
1281
- method: "GET",
1282
- timeoutMs: 30_000,
1283
- });
1284
- return jsonResult({
1285
- error: payload?.error || payload?.message || undefined,
1286
- imageUrls: (Array.isArray(payload?.images) ? payload.images : []).map((image) => image?.url).filter(Boolean),
1287
- progress: payload?.progress,
1288
- requestId,
1289
- status: payload?.status,
1290
- });
1291
- }),
1292
- );
1293
-
1294
1104
  // ── 상세페이지(PDP) ─────────────────────────────────────────────────────────
1295
1105
  server.tool(
1296
1106
  "generate_pdp",
package/lib/config.mjs CHANGED
@@ -2,7 +2,7 @@ import { homedir } from "node:os";
2
2
  import path from "node:path";
3
3
 
4
4
  // 프록시 버전 — 서버가 X-AImakeAll-MCP-Version 으로 하한을 강제(426)할 수 있다.
5
- export const MCP_PROXY_VERSION = "0.4.0";
5
+ export const MCP_PROXY_VERSION = "0.4.1";
6
6
 
7
7
  export const DEFAULT_API_BASE = "https://aimakeall.com";
8
8
  export const DEFAULT_COMPANION_URL = "http://127.0.0.1:9876";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aimakeall-mcp",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "AImakeAll MCP 서버 — Claude Code/Codex에서 자연어로 영상 기획·생성·렌더·퍼블리시 (렌더는 로컬 컴패니언)",
5
5
  "type": "module",
6
6
  "bin": {