@icogenie/mcp 0.1.1 → 0.2.0
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 +10 -7
- package/dist/index.js +94 -66
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -64,7 +64,7 @@ generate_icon({
|
|
|
64
64
|
})
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
**Returns:** `{
|
|
67
|
+
**Returns:** `{ sessionId, preview, previews, creditsRemaining, sessionData, suggestions }`
|
|
68
68
|
|
|
69
69
|
### regenerate_icon
|
|
70
70
|
Regenerate a specific icon variation with a custom refinement prompt.
|
|
@@ -73,12 +73,15 @@ Regenerate a specific icon variation with a custom refinement prompt.
|
|
|
73
73
|
|
|
74
74
|
```
|
|
75
75
|
regenerate_icon({
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
sessionId: "abc123", // for single icons
|
|
77
|
+
bundleId: "xyz789", // for bundles (use one or the other)
|
|
78
|
+
index: 0, // which variation (0-based)
|
|
78
79
|
prompt: "Make it more 3D" // optional refinement
|
|
79
80
|
})
|
|
80
81
|
```
|
|
81
82
|
|
|
83
|
+
**Returns:** `{ success, index, preview, creditsRemaining }`
|
|
84
|
+
|
|
82
85
|
### check_credits
|
|
83
86
|
Check your current credit balance.
|
|
84
87
|
|
|
@@ -132,7 +135,7 @@ generate_bundle({
|
|
|
132
135
|
})
|
|
133
136
|
```
|
|
134
137
|
|
|
135
|
-
**Returns:** `{ bundleId, icons: [{ name, preview }],
|
|
138
|
+
**Returns:** `{ bundleId, iconCount, icons: [{ name, description, preview }], pricing, creditsUsed, creditsRemaining }`
|
|
136
139
|
|
|
137
140
|
## Example Workflow
|
|
138
141
|
|
|
@@ -145,19 +148,19 @@ generate_bundle({
|
|
|
145
148
|
2. **Generate a single icon:**
|
|
146
149
|
```
|
|
147
150
|
generate_icon({ prompt: "notification bell icon", style: "outline" })
|
|
148
|
-
→ {
|
|
151
|
+
→ { sessionId: "abc123", preview: "...", creditsRemaining: 49 }
|
|
149
152
|
```
|
|
150
153
|
|
|
151
154
|
3. **Refine if needed:**
|
|
152
155
|
```
|
|
153
|
-
regenerate_icon({
|
|
156
|
+
regenerate_icon({ sessionId: "abc123", index: 0, prompt: "Add a dot indicator" })
|
|
154
157
|
→ { preview: "...", creditsRemaining: 48 }
|
|
155
158
|
```
|
|
156
159
|
|
|
157
160
|
4. **Download final package:**
|
|
158
161
|
```
|
|
159
162
|
download_icon({ generationId: "abc123", outputPath: "./bell-icon.zip" })
|
|
160
|
-
→ { savedTo: "./bell-icon.zip"
|
|
163
|
+
→ { savedTo: "./bell-icon.zip" }
|
|
161
164
|
```
|
|
162
165
|
|
|
163
166
|
## Bundle Workflow
|
package/dist/index.js
CHANGED
|
@@ -162,15 +162,32 @@ function readReferenceImage(filePath) {
|
|
|
162
162
|
const mimeType = ext === ".png" ? "image/png" : ext === ".webp" ? "image/webp" : "image/jpeg";
|
|
163
163
|
return { data: buffer.toString("base64"), mimeType };
|
|
164
164
|
}
|
|
165
|
-
async function request2(endpoint,
|
|
166
|
-
const
|
|
165
|
+
async function request2(endpoint, options = {}, requireAuth = true) {
|
|
166
|
+
const { method = "POST", body, params } = options;
|
|
167
|
+
let url = `${getApiUrl()}/api${endpoint}`;
|
|
168
|
+
if (params && Object.keys(params).length > 0) {
|
|
169
|
+
url += `?${new URLSearchParams(params).toString()}`;
|
|
170
|
+
}
|
|
167
171
|
const makeRequest = async (sessionToken) => {
|
|
168
|
-
const
|
|
172
|
+
const headers = {};
|
|
173
|
+
if (sessionToken) {
|
|
174
|
+
headers["Authorization"] = `Bearer ${sessionToken}`;
|
|
175
|
+
}
|
|
176
|
+
if (body) {
|
|
177
|
+
headers["Content-Type"] = "application/json";
|
|
178
|
+
}
|
|
169
179
|
const response = await fetch(url, {
|
|
170
|
-
method
|
|
171
|
-
headers
|
|
172
|
-
body: JSON.stringify(
|
|
180
|
+
method,
|
|
181
|
+
headers,
|
|
182
|
+
...body && { body: JSON.stringify(body) }
|
|
173
183
|
});
|
|
184
|
+
const contentType = response.headers.get("content-type");
|
|
185
|
+
if (contentType?.includes("application/zip")) {
|
|
186
|
+
if (!response.ok) {
|
|
187
|
+
throw new ApiError("Download failed", response.status);
|
|
188
|
+
}
|
|
189
|
+
return response;
|
|
190
|
+
}
|
|
174
191
|
const data = await response.json();
|
|
175
192
|
if (response.status === 401 && requireAuth) {
|
|
176
193
|
const newCreds = await handleAuthError();
|
|
@@ -192,44 +209,59 @@ async function request2(endpoint, body, requireAuth = true) {
|
|
|
192
209
|
return makeRequest();
|
|
193
210
|
}
|
|
194
211
|
async function generate(options) {
|
|
195
|
-
return request2("/generate", {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
212
|
+
return request2("/generate-preview", {
|
|
213
|
+
body: {
|
|
214
|
+
prompt: options.prompt,
|
|
215
|
+
variations: options.variations || 1,
|
|
216
|
+
style: options.style || "solid",
|
|
217
|
+
...options.referenceImage && { referenceImage: options.referenceImage }
|
|
218
|
+
}
|
|
200
219
|
});
|
|
201
220
|
}
|
|
202
221
|
async function regenerate(options) {
|
|
203
|
-
return request2("/regenerate", {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
222
|
+
return request2("/regenerate-icon", {
|
|
223
|
+
body: {
|
|
224
|
+
sessionId: options.sessionId,
|
|
225
|
+
bundleId: options.bundleId,
|
|
226
|
+
index: options.index,
|
|
227
|
+
prompt: options.prompt
|
|
228
|
+
}
|
|
208
229
|
});
|
|
209
230
|
}
|
|
210
231
|
async function getCredits() {
|
|
211
|
-
return request2("/
|
|
232
|
+
return request2("/auth/session", { method: "GET" });
|
|
212
233
|
}
|
|
213
234
|
async function download(options) {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
235
|
+
const params = {};
|
|
236
|
+
if (options.generationId) params.generation_id = options.generationId;
|
|
237
|
+
if (options.bundleId) params.bundle_id = options.bundleId;
|
|
238
|
+
const response = await request2("/download", {
|
|
239
|
+
method: "GET",
|
|
240
|
+
params
|
|
217
241
|
});
|
|
242
|
+
const contentDisposition = response.headers.get("content-disposition");
|
|
243
|
+
const filenameMatch = contentDisposition?.match(/filename="?([^";\n]+)"?/);
|
|
244
|
+
const filename = filenameMatch?.[1] || `icogenie-${(options.generationId || options.bundleId || "export").slice(0, 8)}.zip`;
|
|
245
|
+
return { response, filename };
|
|
218
246
|
}
|
|
219
247
|
async function normalizeBundle(options) {
|
|
220
|
-
return request2("/normalize", {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
248
|
+
return request2("/normalize-bundle", {
|
|
249
|
+
body: {
|
|
250
|
+
description: options.description,
|
|
251
|
+
targetCount: options.targetCount,
|
|
252
|
+
style: options.style
|
|
253
|
+
}
|
|
224
254
|
});
|
|
225
255
|
}
|
|
226
256
|
async function generateBundle(options) {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
257
|
+
const bundleId = options.bundleId || crypto.randomUUID();
|
|
258
|
+
return request2("/generate-bundle-preview", {
|
|
259
|
+
body: {
|
|
260
|
+
bundleId,
|
|
261
|
+
icons: options.icons,
|
|
262
|
+
style: options.style || "solid",
|
|
263
|
+
...options.referenceImage && { referenceImage: options.referenceImage }
|
|
264
|
+
}
|
|
233
265
|
});
|
|
234
266
|
}
|
|
235
267
|
|
|
@@ -258,37 +290,38 @@ async function generateIcon(args) {
|
|
|
258
290
|
referenceImage: refImage
|
|
259
291
|
});
|
|
260
292
|
return {
|
|
261
|
-
|
|
293
|
+
sessionId: result.sessionId,
|
|
262
294
|
preview: result.preview,
|
|
263
|
-
|
|
264
|
-
creditsRemaining: result.
|
|
265
|
-
|
|
295
|
+
previews: result.previews,
|
|
296
|
+
creditsRemaining: result.credits,
|
|
297
|
+
sessionData: result.sessionData,
|
|
298
|
+
suggestions: result.suggestions
|
|
266
299
|
};
|
|
267
300
|
}
|
|
268
301
|
|
|
269
302
|
// src/tools/regenerate.ts
|
|
270
303
|
import { z as z2 } from "zod";
|
|
271
304
|
var regenerateIconSchema = {
|
|
272
|
-
|
|
305
|
+
sessionId: z2.string().optional().describe("For single icon variations"),
|
|
273
306
|
bundleId: z2.string().optional().describe("For bundle icons"),
|
|
274
307
|
index: z2.number().describe("Which variation/icon to regenerate (0-based)"),
|
|
275
308
|
prompt: z2.string().optional().describe("Custom refinement prompt")
|
|
276
309
|
};
|
|
277
310
|
async function regenerateIcon(args) {
|
|
278
|
-
if (!args.
|
|
279
|
-
throw new Error("Must provide either
|
|
311
|
+
if (!args.sessionId && !args.bundleId) {
|
|
312
|
+
throw new Error("Must provide either sessionId or bundleId");
|
|
280
313
|
}
|
|
281
314
|
const result = await regenerate({
|
|
282
|
-
|
|
315
|
+
sessionId: args.sessionId,
|
|
283
316
|
bundleId: args.bundleId,
|
|
284
317
|
index: args.index,
|
|
285
318
|
prompt: args.prompt
|
|
286
319
|
});
|
|
287
320
|
return {
|
|
288
321
|
success: result.success,
|
|
322
|
+
index: result.index,
|
|
289
323
|
preview: result.preview,
|
|
290
|
-
|
|
291
|
-
creditsRemaining: result.creditsRemaining
|
|
324
|
+
creditsRemaining: result.credits
|
|
292
325
|
};
|
|
293
326
|
}
|
|
294
327
|
|
|
@@ -315,27 +348,23 @@ async function downloadIcon(args) {
|
|
|
315
348
|
if (!args.generationId && !args.bundleId) {
|
|
316
349
|
throw new Error("Must provide either generationId or bundleId");
|
|
317
350
|
}
|
|
318
|
-
const
|
|
351
|
+
const { response, filename } = await download({
|
|
319
352
|
generationId: args.generationId,
|
|
320
353
|
bundleId: args.bundleId
|
|
321
354
|
});
|
|
322
|
-
const
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
355
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
356
|
+
const zipBuffer = Buffer.from(arrayBuffer);
|
|
357
|
+
const result = {
|
|
358
|
+
success: true,
|
|
359
|
+
filename
|
|
327
360
|
};
|
|
328
361
|
if (args.outputPath) {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
response.savedTo = args.outputPath;
|
|
362
|
+
writeFileSync(args.outputPath, zipBuffer);
|
|
363
|
+
result.savedTo = args.outputPath;
|
|
332
364
|
} else {
|
|
333
|
-
|
|
334
|
-
data: result.bundle.data,
|
|
335
|
-
filename: result.bundle.filename
|
|
336
|
-
};
|
|
365
|
+
result.bundleData = zipBuffer.toString("base64");
|
|
337
366
|
}
|
|
338
|
-
return
|
|
367
|
+
return result;
|
|
339
368
|
}
|
|
340
369
|
|
|
341
370
|
// src/tools/normalize-bundle.ts
|
|
@@ -379,8 +408,8 @@ var generateBundleSchema = {
|
|
|
379
408
|
}).optional().describe("Base64-encoded reference image")
|
|
380
409
|
};
|
|
381
410
|
async function generateBundleTool(args) {
|
|
382
|
-
if (!args.icons
|
|
383
|
-
throw new Error("Must provide
|
|
411
|
+
if (!args.icons) {
|
|
412
|
+
throw new Error("Must provide icons array (use normalize_bundle first to get icon list)");
|
|
384
413
|
}
|
|
385
414
|
let refImage;
|
|
386
415
|
if (args.referenceImagePath) {
|
|
@@ -390,21 +419,20 @@ async function generateBundleTool(args) {
|
|
|
390
419
|
}
|
|
391
420
|
const result = await generateBundle({
|
|
392
421
|
icons: args.icons,
|
|
393
|
-
description: args.description,
|
|
394
|
-
targetCount: args.targetCount,
|
|
395
422
|
style: args.style || "solid",
|
|
396
423
|
referenceImage: refImage
|
|
397
424
|
});
|
|
398
425
|
return {
|
|
399
426
|
bundleId: result.bundleId,
|
|
400
|
-
iconCount: result.
|
|
401
|
-
icons: result.
|
|
427
|
+
iconCount: result.previews.length,
|
|
428
|
+
icons: result.previews.map((icon) => ({
|
|
402
429
|
name: icon.name,
|
|
403
430
|
description: icon.description,
|
|
404
431
|
preview: icon.preview
|
|
405
432
|
})),
|
|
406
|
-
|
|
407
|
-
|
|
433
|
+
pricing: result.pricing,
|
|
434
|
+
creditsUsed: result.creditsUsed,
|
|
435
|
+
creditsRemaining: result.credits
|
|
408
436
|
};
|
|
409
437
|
}
|
|
410
438
|
|
|
@@ -418,7 +446,7 @@ function createServer() {
|
|
|
418
446
|
"generate_icon",
|
|
419
447
|
{
|
|
420
448
|
title: "Generate Icon",
|
|
421
|
-
description: "Generate an AI-powered icon preview from a text description. Costs 1 credit. Returns a generationId for download.",
|
|
449
|
+
description: "Generate an AI-powered icon preview from a text description. Costs 1 credit. Returns a generationId for download. After generation, save the preview image to the user's working directory and display it.",
|
|
422
450
|
inputSchema: generateIconSchema
|
|
423
451
|
},
|
|
424
452
|
async (args) => {
|
|
@@ -433,7 +461,7 @@ function createServer() {
|
|
|
433
461
|
"regenerate_icon",
|
|
434
462
|
{
|
|
435
463
|
title: "Regenerate Icon",
|
|
436
|
-
description: "Regenerate a specific icon variation with an optional custom prompt. Costs 1 credit. Use with generationId (single) or bundleId (bundle).",
|
|
464
|
+
description: "Regenerate a specific icon variation with an optional custom prompt. Costs 1 credit. Use with generationId (single) or bundleId (bundle). After regeneration, save and display the new preview.",
|
|
437
465
|
inputSchema: regenerateIconSchema
|
|
438
466
|
},
|
|
439
467
|
async (args) => {
|
|
@@ -463,7 +491,7 @@ function createServer() {
|
|
|
463
491
|
"download_icon",
|
|
464
492
|
{
|
|
465
493
|
title: "Download Icon",
|
|
466
|
-
description: "Download the final SVG + PNG package for an icon. Costs 5 credits (single) or 4 credits/icon (bundle). Provide outputPath to save to file.",
|
|
494
|
+
description: "Download the final SVG + PNG package for an icon. Costs 5 credits (single) or 4 credits/icon (bundle). Provide outputPath to save to file. Always save to the user's working directory with a descriptive filename.",
|
|
467
495
|
inputSchema: downloadIconSchema
|
|
468
496
|
},
|
|
469
497
|
async (args) => {
|
|
@@ -493,7 +521,7 @@ function createServer() {
|
|
|
493
521
|
"generate_bundle",
|
|
494
522
|
{
|
|
495
523
|
title: "Generate Bundle",
|
|
496
|
-
description: "Generate a bundle of icons from an icon list. Costs 1 credit per icon. Use normalize_bundle first to plan, or provide icons directly.",
|
|
524
|
+
description: "Generate a bundle of icons from an icon list. Costs 1 credit per icon. Use normalize_bundle first to plan, or provide icons directly. After generation, save preview images to the user's working directory and display them.",
|
|
497
525
|
inputSchema: generateBundleSchema
|
|
498
526
|
},
|
|
499
527
|
async (args) => {
|