meigen 0.1.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 +242 -0
- package/README.zh-CN.md +242 -0
- package/bin/meigen-mcp.js +2 -0
- package/data/trending-prompts.json +26737 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +71 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/meigen-api.d.ts +64 -0
- package/dist/lib/meigen-api.d.ts.map +1 -0
- package/dist/lib/meigen-api.js +118 -0
- package/dist/lib/meigen-api.js.map +1 -0
- package/dist/lib/prompt-library.d.ts +44 -0
- package/dist/lib/prompt-library.d.ts.map +1 -0
- package/dist/lib/prompt-library.js +130 -0
- package/dist/lib/prompt-library.js.map +1 -0
- package/dist/lib/prompts.d.ts +21 -0
- package/dist/lib/prompts.d.ts.map +1 -0
- package/dist/lib/prompts.js +116 -0
- package/dist/lib/prompts.js.map +1 -0
- package/dist/lib/providers/comfyui.d.ts +82 -0
- package/dist/lib/providers/comfyui.d.ts.map +1 -0
- package/dist/lib/providers/comfyui.js +436 -0
- package/dist/lib/providers/comfyui.js.map +1 -0
- package/dist/lib/providers/gemini.d.ts +13 -0
- package/dist/lib/providers/gemini.d.ts.map +1 -0
- package/dist/lib/providers/gemini.js +63 -0
- package/dist/lib/providers/gemini.js.map +1 -0
- package/dist/lib/providers/openai.d.ts +14 -0
- package/dist/lib/providers/openai.d.ts.map +1 -0
- package/dist/lib/providers/openai.js +75 -0
- package/dist/lib/providers/openai.js.map +1 -0
- package/dist/lib/providers/types.d.ts +22 -0
- package/dist/lib/providers/types.d.ts.map +1 -0
- package/dist/lib/providers/types.js +7 -0
- package/dist/lib/providers/types.js.map +1 -0
- package/dist/lib/semaphore.d.ts +13 -0
- package/dist/lib/semaphore.d.ts.map +1 -0
- package/dist/lib/semaphore.js +32 -0
- package/dist/lib/semaphore.js.map +1 -0
- package/dist/lib/upload.d.ts +17 -0
- package/dist/lib/upload.d.ts.map +1 -0
- package/dist/lib/upload.js +135 -0
- package/dist/lib/upload.js.map +1 -0
- package/dist/server.d.ts +7 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +163 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/comfyui-workflow.d.ts +17 -0
- package/dist/tools/comfyui-workflow.d.ts.map +1 -0
- package/dist/tools/comfyui-workflow.js +230 -0
- package/dist/tools/comfyui-workflow.js.map +1 -0
- package/dist/tools/enhance-prompt.d.ts +12 -0
- package/dist/tools/enhance-prompt.d.ts.map +1 -0
- package/dist/tools/enhance-prompt.js +27 -0
- package/dist/tools/enhance-prompt.js.map +1 -0
- package/dist/tools/generate-image.d.ts +23 -0
- package/dist/tools/generate-image.d.ts.map +1 -0
- package/dist/tools/generate-image.js +266 -0
- package/dist/tools/generate-image.js.map +1 -0
- package/dist/tools/get-inspiration.d.ts +12 -0
- package/dist/tools/get-inspiration.d.ts.map +1 -0
- package/dist/tools/get-inspiration.js +111 -0
- package/dist/tools/get-inspiration.js.map +1 -0
- package/dist/tools/list-models.d.ts +13 -0
- package/dist/tools/list-models.d.ts.map +1 -0
- package/dist/tools/list-models.js +104 -0
- package/dist/tools/list-models.js.map +1 -0
- package/dist/tools/search-gallery.d.ts +15 -0
- package/dist/tools/search-gallery.d.ts.map +1 -0
- package/dist/tools/search-gallery.js +78 -0
- package/dist/tools/search-gallery.js.map +1 -0
- package/dist/tools/upload-reference-image.d.ts +13 -0
- package/dist/tools/upload-reference-image.d.ts.map +1 -0
- package/dist/tools/upload-reference-image.js +69 -0
- package/dist/tools/upload-reference-image.js.map +1 -0
- package/package.json +45 -0
- package/skills/setup/SKILL.md +324 -0
- package/skills/visual-creative/SKILL.md +185 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* search_gallery Tool — free, no auth required
|
|
4
|
+
* Searches the local curated prompt library (1300+ high-quality prompts)
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.searchGallerySchema = void 0;
|
|
8
|
+
exports.registerSearchGallery = registerSearchGallery;
|
|
9
|
+
const zod_1 = require("zod");
|
|
10
|
+
const prompt_library_js_1 = require("../lib/prompt-library.js");
|
|
11
|
+
exports.searchGallerySchema = {
|
|
12
|
+
query: zod_1.z.string().optional()
|
|
13
|
+
.describe('Search keywords (e.g., "cyberpunk", "product photo", "portrait"). Leave empty to browse by category or get random picks.'),
|
|
14
|
+
category: zod_1.z.enum(['3D', 'App', 'Food', 'Girl', 'JSON', 'Other', 'Photograph', 'Product']).optional()
|
|
15
|
+
.describe('Filter by category. Available: 3D, App, Food, Girl, JSON, Other, Photograph, Product'),
|
|
16
|
+
limit: zod_1.z.number().min(1).max(20).optional().default(5)
|
|
17
|
+
.describe('Number of results (1-20, default 5)'),
|
|
18
|
+
offset: zod_1.z.number().min(0).optional().default(0)
|
|
19
|
+
.describe('Pagination offset'),
|
|
20
|
+
sortBy: zod_1.z.enum(['rank', 'likes', 'views', 'date']).optional().default('rank')
|
|
21
|
+
.describe('Sort order when browsing without search query (default: rank)'),
|
|
22
|
+
};
|
|
23
|
+
function registerSearchGallery(server) {
|
|
24
|
+
server.tool('search_gallery', 'Search 1300+ curated AI image prompts with preview images. Results include image URLs — render them as markdown images () so users can visually browse and pick styles. Use when users need inspiration, want to explore styles, or say "generate an image" without a specific idea.', exports.searchGallerySchema, { readOnlyHint: true }, async ({ query, category, limit, offset, sortBy }) => {
|
|
25
|
+
// No search criteria — return random picks
|
|
26
|
+
if (!query && !category && offset === 0) {
|
|
27
|
+
const random = (0, prompt_library_js_1.getRandomPrompts)(limit);
|
|
28
|
+
const stats = (0, prompt_library_js_1.getLibraryStats)();
|
|
29
|
+
const header = `Curated Prompt Library: ${stats.total} trending prompts\nCategories: ${Object.entries(stats.categories).map(([k, v]) => `${k} (${v})`).join(', ')}\n\nHere are ${limit} random picks — show the preview images to the user:\n`;
|
|
30
|
+
return {
|
|
31
|
+
content: [{
|
|
32
|
+
type: 'text',
|
|
33
|
+
text: header + formatResults(random),
|
|
34
|
+
}],
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
const results = (0, prompt_library_js_1.searchPrompts)({ query, category, limit, offset, sortBy });
|
|
38
|
+
if (results.length === 0) {
|
|
39
|
+
const suggestion = category
|
|
40
|
+
? `No results for "${query || ''}" in category "${category}". Try a different keyword or remove the category filter.`
|
|
41
|
+
: `No results for "${query}". Try broader keywords like "portrait", "landscape", "product", "anime".`;
|
|
42
|
+
return {
|
|
43
|
+
content: [{
|
|
44
|
+
type: 'text',
|
|
45
|
+
text: suggestion,
|
|
46
|
+
}],
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
const searchDesc = [
|
|
50
|
+
query ? `"${query}"` : null,
|
|
51
|
+
category ? `category: ${category}` : null,
|
|
52
|
+
].filter(Boolean).join(', ');
|
|
53
|
+
const text = `Found ${results.length} results${searchDesc ? ` for ${searchDesc}` : ''}:\n\n${formatResults(results)}\n\nShow the preview images above to the user so they can visually browse. Use get_inspiration(imageId) to get the full prompt and all images for any entry the user likes.`;
|
|
54
|
+
return {
|
|
55
|
+
content: [{
|
|
56
|
+
type: 'text',
|
|
57
|
+
text,
|
|
58
|
+
}],
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function formatResults(results) {
|
|
63
|
+
return results.map((item, i) => {
|
|
64
|
+
// Truncate prompt to first 150 chars for preview
|
|
65
|
+
const promptPreview = item.prompt.length > 150
|
|
66
|
+
? item.prompt.slice(0, 150).replace(/\n/g, ' ') + '...'
|
|
67
|
+
: item.prompt.replace(/\n/g, ' ');
|
|
68
|
+
const parts = [
|
|
69
|
+
`${i + 1}. **#${item.rank}** by ${item.author_name} — ${item.categories.join(', ')}`,
|
|
70
|
+
` `,
|
|
71
|
+
` Prompt: ${promptPreview}`,
|
|
72
|
+
` Stats: ${item.likes} likes, ${item.views.toLocaleString()} views`,
|
|
73
|
+
` ID: ${item.id}`,
|
|
74
|
+
];
|
|
75
|
+
return parts.join('\n');
|
|
76
|
+
}).join('\n\n');
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=search-gallery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-gallery.js","sourceRoot":"","sources":["../../src/tools/search-gallery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* upload_reference_image Tool
|
|
3
|
+
* Compresses a local image and uploads it to R2, returning a public URL
|
|
4
|
+
* for use as referenceImages in generate_image.
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
8
|
+
import type { MeiGenConfig } from '../config.js';
|
|
9
|
+
export declare const uploadReferenceImageSchema: {
|
|
10
|
+
filePath: z.ZodString;
|
|
11
|
+
};
|
|
12
|
+
export declare function registerUploadReferenceImage(server: McpServer, config: MeiGenConfig): void;
|
|
13
|
+
//# sourceMappingURL=upload-reference-image.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-reference-image.d.ts","sourceRoot":"","sources":["../../src/tools/upload-reference-image.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAGhD,eAAO,MAAM,0BAA0B;;CAGtC,CAAA;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,QAoDnF"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* upload_reference_image Tool
|
|
4
|
+
* Compresses a local image and uploads it to R2, returning a public URL
|
|
5
|
+
* for use as referenceImages in generate_image.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.uploadReferenceImageSchema = void 0;
|
|
9
|
+
exports.registerUploadReferenceImage = registerUploadReferenceImage;
|
|
10
|
+
const zod_1 = require("zod");
|
|
11
|
+
const fs_1 = require("fs");
|
|
12
|
+
const upload_js_1 = require("../lib/upload.js");
|
|
13
|
+
exports.uploadReferenceImageSchema = {
|
|
14
|
+
filePath: zod_1.z.string()
|
|
15
|
+
.describe('Absolute path to a local image file (JPEG, PNG, WebP, or GIF). The image will be automatically compressed if needed and uploaded for use as a reference image in generate_image.'),
|
|
16
|
+
};
|
|
17
|
+
function registerUploadReferenceImage(server, config) {
|
|
18
|
+
server.tool('upload_reference_image', 'Upload a local image for use as a reference in generate_image. Compresses large images (max 2MB, max 2048px) and returns a public URL. Call this when the user wants to use a local file as a reference image.', exports.uploadReferenceImageSchema, { readOnlyHint: false }, async ({ filePath }) => {
|
|
19
|
+
// Validate file exists
|
|
20
|
+
if (!(0, fs_1.existsSync)(filePath)) {
|
|
21
|
+
return {
|
|
22
|
+
content: [{
|
|
23
|
+
type: 'text',
|
|
24
|
+
text: `File not found: ${filePath}`,
|
|
25
|
+
}],
|
|
26
|
+
isError: true,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
const result = await (0, upload_js_1.processAndUploadImage)(filePath, config);
|
|
31
|
+
const compressed = result.originalSize !== result.compressedSize;
|
|
32
|
+
const sizeInfo = compressed
|
|
33
|
+
? `Compressed: ${formatSize(result.originalSize)} → ${formatSize(result.compressedSize)}`
|
|
34
|
+
: `Size: ${formatSize(result.originalSize)} (no compression needed)`;
|
|
35
|
+
return {
|
|
36
|
+
content: [{
|
|
37
|
+
type: 'text',
|
|
38
|
+
text: [
|
|
39
|
+
`Reference image uploaded successfully.`,
|
|
40
|
+
``,
|
|
41
|
+
`URL: ${result.publicUrl}`,
|
|
42
|
+
sizeInfo,
|
|
43
|
+
``,
|
|
44
|
+
`Use this URL in generate_image's referenceImages parameter:`,
|
|
45
|
+
`generate_image(prompt="...", referenceImages=["${result.publicUrl}"])`,
|
|
46
|
+
].join('\n'),
|
|
47
|
+
}],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
52
|
+
return {
|
|
53
|
+
content: [{
|
|
54
|
+
type: 'text',
|
|
55
|
+
text: `Failed to upload reference image: ${message}`,
|
|
56
|
+
}],
|
|
57
|
+
isError: true,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
function formatSize(bytes) {
|
|
63
|
+
if (bytes < 1024)
|
|
64
|
+
return `${bytes}B`;
|
|
65
|
+
if (bytes < 1024 * 1024)
|
|
66
|
+
return `${(bytes / 1024).toFixed(1)}KB`;
|
|
67
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=upload-reference-image.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-reference-image.js","sourceRoot":"","sources":["../../src/tools/upload-reference-image.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;AAaH,oEAoDC;AA/DD,6BAAuB;AACvB,2BAA+B;AAG/B,gDAAwD;AAE3C,QAAA,0BAA0B,GAAG;IACxC,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE;SACjB,QAAQ,CAAC,kLAAkL,CAAC;CAChM,CAAA;AAED,SAAgB,4BAA4B,CAAC,MAAiB,EAAE,MAAoB;IAClF,MAAM,CAAC,IAAI,CACT,wBAAwB,EACxB,gNAAgN,EAChN,kCAA0B,EAC1B,EAAE,YAAY,EAAE,KAAK,EAAE,EACvB,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE;QACrB,uBAAuB;QACvB,IAAI,CAAC,IAAA,eAAU,EAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,OAAO;gBACL,OAAO,EAAE,CAAC;wBACR,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,mBAAmB,QAAQ,EAAE;qBACpC,CAAC;gBACF,OAAO,EAAE,IAAI;aACd,CAAA;QACH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAA,iCAAqB,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;YAE5D,MAAM,UAAU,GAAG,MAAM,CAAC,YAAY,KAAK,MAAM,CAAC,cAAc,CAAA;YAChE,MAAM,QAAQ,GAAG,UAAU;gBACzB,CAAC,CAAC,eAAe,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,UAAU,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE;gBACzF,CAAC,CAAC,SAAS,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,0BAA0B,CAAA;YAEtE,OAAO;gBACL,OAAO,EAAE,CAAC;wBACR,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE;4BACJ,wCAAwC;4BACxC,EAAE;4BACF,QAAQ,MAAM,CAAC,SAAS,EAAE;4BAC1B,QAAQ;4BACR,EAAE;4BACF,6DAA6D;4BAC7D,kDAAkD,MAAM,CAAC,SAAS,KAAK;yBACxE,CAAC,IAAI,CAAC,IAAI,CAAC;qBACb,CAAC;aACH,CAAA;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;YACtE,OAAO;gBACL,OAAO,EAAE,CAAC;wBACR,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,qCAAqC,OAAO,EAAE;qBACrD,CAAC;gBACF,OAAO,EAAE,IAAI;aACd,CAAA;QACH,CAAC;IACH,CAAC,CACF,CAAA;AACH,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,IAAI,KAAK,GAAG,IAAI;QAAE,OAAO,GAAG,KAAK,GAAG,CAAA;IACpC,IAAI,KAAK,GAAG,IAAI,GAAG,IAAI;QAAE,OAAO,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA;IAChE,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA;AAClD,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "meigen",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Visual creative expert plugin — search inspiration, enhance prompts, and generate AI images with intelligent workflow orchestration",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"meigen": "bin/meigen-mcp.js",
|
|
9
|
+
"meigen-mcp": "bin/meigen-mcp.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"bin/",
|
|
13
|
+
"dist/",
|
|
14
|
+
"data/",
|
|
15
|
+
"skills/"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"dev": "tsx src/index.ts",
|
|
20
|
+
"typecheck": "tsc --noEmit"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"mcp",
|
|
24
|
+
"ai",
|
|
25
|
+
"image-generation",
|
|
26
|
+
"claude",
|
|
27
|
+
"meigen",
|
|
28
|
+
"prompt-engineering"
|
|
29
|
+
],
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=18.0.0"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
36
|
+
"sharp": "^0.34.5",
|
|
37
|
+
"zod": "^3.25.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^20.0.0",
|
|
41
|
+
"@types/sharp": "^0.31.1",
|
|
42
|
+
"tsx": "^4.0.0",
|
|
43
|
+
"typescript": "^5.0.0"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: setup
|
|
3
|
+
description: >-
|
|
4
|
+
Configure MeiGen plugin provider and API keys. Use this when the user runs
|
|
5
|
+
/meigen:setup, asks to "configure meigen", "set up image generation",
|
|
6
|
+
"add API key", or needs help configuring the plugin.
|
|
7
|
+
disable-model-invocation: true
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# MeiGen Plugin Setup
|
|
11
|
+
|
|
12
|
+
You are guiding the user through configuring the MeiGen plugin for image generation. Follow this flow step by step.
|
|
13
|
+
|
|
14
|
+
## Step 1: Welcome
|
|
15
|
+
|
|
16
|
+
First, check if a config file already exists:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
cat ~/.config/meigen/config.json 2>/dev/null
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Also check for existing ComfyUI workflows:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
ls ~/.config/meigen/workflows/*.json 2>/dev/null
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
If config exists, show the current configuration (mask API keys: show first 10 chars + "...") and any saved workflows. Ask if they want to reconfigure.
|
|
29
|
+
|
|
30
|
+
If no config exists, present this introduction:
|
|
31
|
+
|
|
32
|
+
> **MeiGen Plugin Configuration**
|
|
33
|
+
>
|
|
34
|
+
> This is optional. Without configuration, you can still use free features:
|
|
35
|
+
> - Search gallery for inspiration and prompts
|
|
36
|
+
> - Enhance simple ideas into professional prompts
|
|
37
|
+
> - Browse available AI models
|
|
38
|
+
>
|
|
39
|
+
> Configuring a provider unlocks **image generation**.
|
|
40
|
+
|
|
41
|
+
Then proceed to Step 2.
|
|
42
|
+
|
|
43
|
+
## Step 2: Choose Provider
|
|
44
|
+
|
|
45
|
+
Present these options to the user:
|
|
46
|
+
|
|
47
|
+
### Option A: MeiGen Platform (Recommended)
|
|
48
|
+
|
|
49
|
+
- Supports **Nanobanana Pro**, **Seedream 4.5**, **Midjourney Niji7** and more
|
|
50
|
+
- Free daily credits included
|
|
51
|
+
- Reference image support for style transfer
|
|
52
|
+
- No additional accounts needed — just get a token from meigen.ai
|
|
53
|
+
|
|
54
|
+
### Option B: ComfyUI (Local)
|
|
55
|
+
|
|
56
|
+
- Use your **local ComfyUI** installation for image generation
|
|
57
|
+
- Full control over models, samplers, and workflow settings
|
|
58
|
+
- No cloud API needed — runs entirely on your machine
|
|
59
|
+
- Import your own workflow from ComfyUI
|
|
60
|
+
|
|
61
|
+
### Option C: Custom OpenAI-Compatible API
|
|
62
|
+
|
|
63
|
+
- Use your own **OpenAI**, **Together AI**, **Fireworks AI**, or any OpenAI-compatible service
|
|
64
|
+
- Bring your own API key and billing
|
|
65
|
+
- Supports any model that uses the OpenAI `/v1/images/generations` endpoint
|
|
66
|
+
|
|
67
|
+
### Option D: Import from curl Example
|
|
68
|
+
|
|
69
|
+
- Already have a working curl command from your API provider's docs? Paste it directly!
|
|
70
|
+
- We'll automatically extract the API key, base URL, and model name
|
|
71
|
+
|
|
72
|
+
### Option E: Skip image generation for now
|
|
73
|
+
|
|
74
|
+
- Free features still available (inspiration search, prompt enhancement, model listing)
|
|
75
|
+
- You can run `/meigen:setup` anytime later to enable image generation
|
|
76
|
+
|
|
77
|
+
If user chooses **Skip**, say goodbye and exit. Otherwise continue to the appropriate Step 3.
|
|
78
|
+
|
|
79
|
+
## Step 3A: MeiGen Platform Setup
|
|
80
|
+
|
|
81
|
+
Ask the user:
|
|
82
|
+
|
|
83
|
+
> Do you already have a MeiGen API token, or do you need to create one?
|
|
84
|
+
|
|
85
|
+
### If they need to create one:
|
|
86
|
+
|
|
87
|
+
Provide these instructions:
|
|
88
|
+
|
|
89
|
+
1. Go to **https://www.meigen.ai**
|
|
90
|
+
2. Sign in or create an account
|
|
91
|
+
3. Navigate to **Settings** (click your avatar) → **API Keys**
|
|
92
|
+
4. Click **Create API Key**, give it a name
|
|
93
|
+
5. Copy the token (starts with `meigen_sk_`)
|
|
94
|
+
|
|
95
|
+
Then ask them to paste the token.
|
|
96
|
+
|
|
97
|
+
### If they already have one:
|
|
98
|
+
|
|
99
|
+
Ask them to paste their `meigen_sk_...` token.
|
|
100
|
+
|
|
101
|
+
### Validate the token:
|
|
102
|
+
|
|
103
|
+
- Must start with `meigen_sk_`
|
|
104
|
+
- Must be at least 30 characters long
|
|
105
|
+
|
|
106
|
+
If valid, proceed to **Step 4** with this config:
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"meigenApiToken": "<the token>"
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Step 3B: ComfyUI (Local) Setup
|
|
115
|
+
|
|
116
|
+
### 3B-1: Check Connection
|
|
117
|
+
|
|
118
|
+
Ask the user for their ComfyUI server URL:
|
|
119
|
+
|
|
120
|
+
> What is your ComfyUI server URL? (default: `http://localhost:8188`)
|
|
121
|
+
|
|
122
|
+
Test the connection:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
curl -s <URL>/system_stats | head -c 200
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
- **Success**: Show confirmation and continue to 3B-2
|
|
129
|
+
- **Failure**: Tell the user:
|
|
130
|
+
> Cannot connect to ComfyUI at `<URL>`. Please make sure:
|
|
131
|
+
> 1. ComfyUI is running (start it with `python main.py` or your launcher)
|
|
132
|
+
> 2. The URL and port are correct
|
|
133
|
+
> 3. No firewall is blocking the connection
|
|
134
|
+
|
|
135
|
+
### 3B-2: Import Workflow
|
|
136
|
+
|
|
137
|
+
Explain the workflow export process to the user:
|
|
138
|
+
|
|
139
|
+
> To use ComfyUI with this plugin, you need to export a workflow in **API format**:
|
|
140
|
+
>
|
|
141
|
+
> 1. Open ComfyUI in your browser (usually `http://localhost:8188`)
|
|
142
|
+
> 2. Load or create your preferred workflow
|
|
143
|
+
> 3. Click **⚙️ Settings** → enable **"Enable Dev mode options"**
|
|
144
|
+
> 4. Click the **"Save (API Format)"** button that appears
|
|
145
|
+
> 5. Save the downloaded `.json` file somewhere convenient
|
|
146
|
+
|
|
147
|
+
Then ask them to provide the file path:
|
|
148
|
+
|
|
149
|
+
> Please provide the path to your exported workflow JSON file:
|
|
150
|
+
> Example: `~/Downloads/workflow_api.json`
|
|
151
|
+
|
|
152
|
+
Use the `comfyui_workflow` tool with action `import` to import the workflow:
|
|
153
|
+
|
|
154
|
+
- Ask for a short name for the workflow (e.g., "txt2img", "anime", "realistic")
|
|
155
|
+
- Call: `comfyui_workflow import` with `filePath` and `name`
|
|
156
|
+
- Show the detected nodes and parameters to the user for confirmation
|
|
157
|
+
|
|
158
|
+
If the import succeeds, ask if they want to import additional workflows. If yes, repeat this step.
|
|
159
|
+
|
|
160
|
+
### 3B-3: Save Configuration
|
|
161
|
+
|
|
162
|
+
Build the config JSON:
|
|
163
|
+
|
|
164
|
+
```json
|
|
165
|
+
{
|
|
166
|
+
"comfyuiUrl": "<the URL, omit if http://localhost:8188>",
|
|
167
|
+
"comfyuiDefaultWorkflow": "<the first imported workflow name>"
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Proceed to **Step 4** to save. The workflow files are already saved by the import step.
|
|
172
|
+
|
|
173
|
+
## Step 3C: Custom OpenAI-Compatible API Setup
|
|
174
|
+
|
|
175
|
+
Collect the following information. Present common presets first for convenience:
|
|
176
|
+
|
|
177
|
+
### Quick Presets
|
|
178
|
+
|
|
179
|
+
| Service | Base URL | Default Model |
|
|
180
|
+
|---------|----------|---------------|
|
|
181
|
+
| **OpenAI** | `https://api.openai.com` (default) | `gpt-image-1` |
|
|
182
|
+
| **Together AI** | `https://api.together.xyz/v1` | (check their docs) |
|
|
183
|
+
| **Fireworks AI** | `https://api.fireworks.ai/inference/v1` | (check their docs) |
|
|
184
|
+
|
|
185
|
+
Ask the user to either pick a preset or provide custom values.
|
|
186
|
+
|
|
187
|
+
### Required Fields
|
|
188
|
+
|
|
189
|
+
1. **API Key** (required): Their API key for the service
|
|
190
|
+
- Example: `sk-...` for OpenAI
|
|
191
|
+
|
|
192
|
+
2. **Base URL** (optional): API endpoint URL
|
|
193
|
+
- Default: `https://api.openai.com`
|
|
194
|
+
- Only needed if using a non-OpenAI service
|
|
195
|
+
|
|
196
|
+
3. **Model Name** (optional): Which model to use
|
|
197
|
+
- Default: `gpt-image-1`
|
|
198
|
+
- Different services use different model names
|
|
199
|
+
|
|
200
|
+
### Optional: Test the connection
|
|
201
|
+
|
|
202
|
+
After collecting the info, suggest testing with curl:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
curl -s <BASE_URL>/v1/models \
|
|
206
|
+
-H "Authorization: Bearer <API_KEY>" | head -c 500
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
This helps catch invalid keys or wrong URLs before saving.
|
|
210
|
+
|
|
211
|
+
Proceed to **Step 4** with config from the collected fields (see bottom of this section for format).
|
|
212
|
+
|
|
213
|
+
Only include fields that differ from defaults. Omit `openaiBaseUrl` if it's `https://api.openai.com`, omit `openaiModel` if it's `gpt-image-1`.
|
|
214
|
+
|
|
215
|
+
## Step 3D: Import from curl Example
|
|
216
|
+
|
|
217
|
+
Ask the user to paste their curl command. Common formats they might paste:
|
|
218
|
+
|
|
219
|
+
**Format 1: Image generation endpoint**
|
|
220
|
+
```bash
|
|
221
|
+
curl https://api.openai.com/v1/images/generations \
|
|
222
|
+
-H "Authorization: Bearer sk-xxx" \
|
|
223
|
+
-H "Content-Type: application/json" \
|
|
224
|
+
-d '{"model": "gpt-image-1", "prompt": "a cat", "n": 1, "size": "1024x1024"}'
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
**Format 2: Simple model list test**
|
|
228
|
+
```bash
|
|
229
|
+
curl https://api.together.xyz/v1/models \
|
|
230
|
+
-H "Authorization: Bearer xxx"
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
**Format 3: With -u flag or other auth styles**
|
|
234
|
+
```bash
|
|
235
|
+
curl -u :sk-xxx https://api.fireworks.ai/inference/v1/images/generations \
|
|
236
|
+
-d '{"model": "accounts/fireworks/models/flux", "prompt": "a cat"}'
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
### Parse the curl command and extract:
|
|
240
|
+
|
|
241
|
+
1. **Base URL**: The URL hostname + base path (strip `/v1/images/generations`, `/v1/models`, etc.)
|
|
242
|
+
- `https://api.openai.com/v1/images/generations` → `https://api.openai.com`
|
|
243
|
+
- `https://api.together.xyz/v1/models` → `https://api.together.xyz/v1`
|
|
244
|
+
- If URL ends with `/v1/...`, keep the `/v1` part only if it's NOT `api.openai.com`
|
|
245
|
+
|
|
246
|
+
2. **API Key**: From `Authorization: Bearer <key>` header, or `-u :<key>` flag, or `--header` variants
|
|
247
|
+
|
|
248
|
+
3. **Model**: From the JSON request body `"model": "<value>"` if present
|
|
249
|
+
|
|
250
|
+
### Show parsed results for confirmation:
|
|
251
|
+
|
|
252
|
+
> I extracted the following from your curl command:
|
|
253
|
+
> - **API Key**: `sk-xxx...` (first 10 chars)
|
|
254
|
+
> - **Base URL**: `https://api.together.xyz/v1`
|
|
255
|
+
> - **Model**: `black-forest-labs/FLUX.1-schnell`
|
|
256
|
+
>
|
|
257
|
+
> Does this look correct?
|
|
258
|
+
|
|
259
|
+
If user confirms, proceed to **Step 4**. If not, let them correct individual fields.
|
|
260
|
+
|
|
261
|
+
## Step 4: Save Configuration
|
|
262
|
+
|
|
263
|
+
Build the config JSON based on the chosen provider:
|
|
264
|
+
|
|
265
|
+
**For MeiGen:**
|
|
266
|
+
```json
|
|
267
|
+
{
|
|
268
|
+
"meigenApiToken": "<the token>"
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
**For ComfyUI:**
|
|
273
|
+
```json
|
|
274
|
+
{
|
|
275
|
+
"comfyuiUrl": "<url, omit if default>",
|
|
276
|
+
"comfyuiDefaultWorkflow": "<workflow name>"
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
**For OpenAI-compatible (manual or curl import):**
|
|
281
|
+
```json
|
|
282
|
+
{
|
|
283
|
+
"openaiApiKey": "<the key>",
|
|
284
|
+
"openaiBaseUrl": "<base url, omit if default>",
|
|
285
|
+
"openaiModel": "<model, omit if default>"
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
Create the config directory and write the file:
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
mkdir -p ~/.config/meigen
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
Then use the Write tool to write the JSON config to `~/.config/meigen/config.json`.
|
|
296
|
+
|
|
297
|
+
**Important**: If the user already has a config file with other providers configured, **merge** the new config into the existing one rather than overwriting. For example, a user might have both MeiGen and ComfyUI configured.
|
|
298
|
+
|
|
299
|
+
After writing, set permissions:
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
chmod 600 ~/.config/meigen/config.json
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
## Step 5: Completion
|
|
306
|
+
|
|
307
|
+
Tell the user:
|
|
308
|
+
|
|
309
|
+
> Configuration saved! To activate the new settings, please **start a new Claude Code session** (close and reopen, or open a new terminal tab).
|
|
310
|
+
>
|
|
311
|
+
> After restarting, you can:
|
|
312
|
+
> - Use `generate_image` to create AI images
|
|
313
|
+
> - Run `list_models` to see available models and workflows
|
|
314
|
+
> - Try: "Generate a beautiful sunset over mountains"
|
|
315
|
+
>
|
|
316
|
+
> You can run `/meigen:setup` again anytime to change your configuration.
|
|
317
|
+
|
|
318
|
+
**For ComfyUI users**, additionally mention:
|
|
319
|
+
|
|
320
|
+
> ComfyUI tips:
|
|
321
|
+
> - Use `comfyui_workflow list` to see your saved workflows
|
|
322
|
+
> - Use `comfyui_workflow view` to see adjustable parameters (steps, CFG, sampler, etc.)
|
|
323
|
+
> - Ask me to change any workflow parameter — e.g., "increase steps to 30" or "switch sampler to dpmpp_2m"
|
|
324
|
+
> - You can import more workflows anytime with `comfyui_workflow import`
|