thumbnailgpt 1.0.1 ā 1.0.3
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 +14 -1
- package/dist/client.d.ts +7 -1
- package/dist/client.js +13 -0
- package/dist/index.js +46 -2
- package/dist/mcp.js +30 -1
- package/dist/types.d.ts +5 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -62,7 +62,8 @@ Add to `claude_desktop_config.json`:
|
|
|
62
62
|
```
|
|
63
63
|
|
|
64
64
|
### Exposed MCP Tools:
|
|
65
|
-
- `thumbnailgpt_generate`: Synthesize YouTube thumbnails with custom prompts, aspect ratios (`16:9`, `9:16`), resolutions (`1K`, `2K`, `4K`), and
|
|
65
|
+
- `thumbnailgpt_generate`: Synthesize YouTube thumbnails with custom prompts, aspect ratios (`16:9`, `9:16`), resolutions (`1K`, `2K`, `4K`), reference images, and creator persona IDs (`personaId`).
|
|
66
|
+
- `thumbnailgpt_get_personas`: Retrieve verified active creator personas (`id`, `name`). Raw image assets and unready personas are strictly protected and never exposed.
|
|
66
67
|
- `thumbnailgpt_get_credits`: Query available credits and subscription status.
|
|
67
68
|
- `thumbnailgpt_list_chats`: List recent Studio conversation sessions.
|
|
68
69
|
- `thumbnailgpt_get_chat`: Retrieve full message history and generated thumbnail URLs.
|
|
@@ -83,11 +84,23 @@ npx thumbnailgpt logout
|
|
|
83
84
|
npx thumbnailgpt whoami
|
|
84
85
|
```
|
|
85
86
|
|
|
87
|
+
### Creator Personas
|
|
88
|
+
```bash
|
|
89
|
+
# List your active creator personas (only ready personas with safe IDs/names are shown)
|
|
90
|
+
npx thumbnailgpt personas list
|
|
91
|
+
|
|
92
|
+
# New personas can only be trained in the Web UI
|
|
93
|
+
npx thumbnailgpt personas add
|
|
94
|
+
```
|
|
95
|
+
|
|
86
96
|
### Generate Thumbnails
|
|
87
97
|
```bash
|
|
88
98
|
# Standard 16:9 1K thumbnail
|
|
89
99
|
npx thumbnailgpt generate "Extreme Minecraft Hardcore Survival"
|
|
90
100
|
|
|
101
|
+
# Generate thumbnail featuring your trained creator persona
|
|
102
|
+
npx thumbnailgpt generate "24-Hour Survival Challenge" --persona <personaId>
|
|
103
|
+
|
|
91
104
|
# 4K resolution saved to local file
|
|
92
105
|
npx thumbnailgpt generate "Cyberpunk Underground Hacker Room" --resolution 4K --output ./thumb.webp
|
|
93
106
|
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CreditBalanceResponse, StudioGenerateOptions, StudioDispatchResult, StudioConversationResponse, GenerationSettledResult } from "./types.js";
|
|
1
|
+
import type { CreditBalanceResponse, StudioGenerateOptions, StudioDispatchResult, StudioConversationResponse, GenerationSettledResult, PersonaItem } from "./types.js";
|
|
2
2
|
export declare class ThumbnailGPTClient {
|
|
3
3
|
private apiKey;
|
|
4
4
|
private apiUrl;
|
|
@@ -20,6 +20,12 @@ export declare class ThumbnailGPTClient {
|
|
|
20
20
|
* List recent studio conversations
|
|
21
21
|
*/
|
|
22
22
|
listChats(): Promise<any>;
|
|
23
|
+
/**
|
|
24
|
+
* Retrieve active, ready-to-use personas for the user.
|
|
25
|
+
* Only 'ready' personas are returned. Raw image URLs, character sheets,
|
|
26
|
+
* error traces, and database internals are strictly redacted.
|
|
27
|
+
*/
|
|
28
|
+
getPersonas(): Promise<PersonaItem[]>;
|
|
23
29
|
/**
|
|
24
30
|
* Asynchronously dispatch and poll until completion
|
|
25
31
|
*/
|
package/dist/client.js
CHANGED
|
@@ -68,6 +68,19 @@ export class ThumbnailGPTClient {
|
|
|
68
68
|
async listChats() {
|
|
69
69
|
return this.request("/api/studio");
|
|
70
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Retrieve active, ready-to-use personas for the user.
|
|
73
|
+
* Only 'ready' personas are returned. Raw image URLs, character sheets,
|
|
74
|
+
* error traces, and database internals are strictly redacted.
|
|
75
|
+
*/
|
|
76
|
+
async getPersonas() {
|
|
77
|
+
const res = await this.request("/api/personas");
|
|
78
|
+
return (res.personas || []).map((p) => ({
|
|
79
|
+
id: p.id,
|
|
80
|
+
name: p.name,
|
|
81
|
+
created_at: p.created_at,
|
|
82
|
+
}));
|
|
83
|
+
}
|
|
71
84
|
/**
|
|
72
85
|
* Asynchronously dispatch and poll until completion
|
|
73
86
|
*/
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ const program = new Command();
|
|
|
9
9
|
program
|
|
10
10
|
.name("thumbnailgpt")
|
|
11
11
|
.description("Official CLI and MCP server for ThumbnailGPT Studio")
|
|
12
|
-
.version("1.0.
|
|
12
|
+
.version("1.0.3");
|
|
13
13
|
// 1. Auth Login
|
|
14
14
|
program
|
|
15
15
|
.command("login")
|
|
@@ -76,6 +76,7 @@ program
|
|
|
76
76
|
.option("--ref <urls...>", "Reference image file paths or URLs (max 5)")
|
|
77
77
|
.option("--yt <url>", "YouTube video URL for reference")
|
|
78
78
|
.option("-c, --chat <chatId>", "Continue an existing studio conversation thread")
|
|
79
|
+
.option("-p, --persona <personaId>", "Creator Persona UUID to feature in the thumbnail")
|
|
79
80
|
.option("-o, --out <filepath>", "Download result directly to file (e.g. ./thumb.png)")
|
|
80
81
|
.option("--async", "Dispatch job and return immediately without waiting")
|
|
81
82
|
.action(async (prompt, options) => {
|
|
@@ -90,6 +91,7 @@ program
|
|
|
90
91
|
resolution: options.res,
|
|
91
92
|
referenceImages: options.ref,
|
|
92
93
|
youtubeUrl: options.yt,
|
|
94
|
+
personaId: options.persona,
|
|
93
95
|
});
|
|
94
96
|
spinner.succeed("Generation dispatched successfully!");
|
|
95
97
|
console.log(`\n${pc.bold("Chat ID:")} ${dispatch.chatId}`);
|
|
@@ -105,6 +107,7 @@ program
|
|
|
105
107
|
resolution: options.res,
|
|
106
108
|
referenceImages: options.ref,
|
|
107
109
|
youtubeUrl: options.yt,
|
|
110
|
+
personaId: options.persona,
|
|
108
111
|
}, (elapsedSec) => {
|
|
109
112
|
spinner.text = `Synthesizing thumbnail with AI [${elapsedSec}s elapsed]...`;
|
|
110
113
|
});
|
|
@@ -245,7 +248,48 @@ chats
|
|
|
245
248
|
process.exit(1);
|
|
246
249
|
}
|
|
247
250
|
});
|
|
248
|
-
// 7.
|
|
251
|
+
// 7. Creator Personas
|
|
252
|
+
const personasCmd = program
|
|
253
|
+
.command("personas")
|
|
254
|
+
.description("Inspect active creator personas for thumbnail generation");
|
|
255
|
+
personasCmd
|
|
256
|
+
.command("list")
|
|
257
|
+
.description("List your active creator personas (only ready personas are shown)")
|
|
258
|
+
.action(async () => {
|
|
259
|
+
try {
|
|
260
|
+
const client = new ThumbnailGPTClient();
|
|
261
|
+
const spinner = ora("Fetching active personas...").start();
|
|
262
|
+
const personas = await client.getPersonas();
|
|
263
|
+
spinner.stop();
|
|
264
|
+
if (personas.length === 0) {
|
|
265
|
+
console.log(pc.yellow("\nNo active personas found."));
|
|
266
|
+
console.log(`Train your first persona in the Web Studio at: ${pc.cyan("https://thumbnailgpt.com/studio")}\n`);
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
console.log(pc.bold("\nActive Creator Personas:"));
|
|
270
|
+
console.log(pc.dim("--------------------------------------------------------------------------------"));
|
|
271
|
+
personas.forEach((p) => {
|
|
272
|
+
const dateStr = p.created_at ? pc.dim(new Date(p.created_at).toLocaleDateString()) : "";
|
|
273
|
+
console.log(`${pc.cyan(p.id)} ${pc.bold(p.name)} ${dateStr}`);
|
|
274
|
+
});
|
|
275
|
+
console.log(pc.dim("--------------------------------------------------------------------------------"));
|
|
276
|
+
console.log(`Use in generation: ${pc.green('npx thumbnailgpt generate "..." --persona <id>')}\n`);
|
|
277
|
+
}
|
|
278
|
+
catch (err) {
|
|
279
|
+
console.error(pc.red(`\nā Error: ${err.message}`));
|
|
280
|
+
process.exit(1);
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
personasCmd
|
|
284
|
+
.command("add")
|
|
285
|
+
.description("Instructions for creating and training a new creator persona")
|
|
286
|
+
.action(() => {
|
|
287
|
+
console.log(pc.bold("\nTraining New Creator Personas:"));
|
|
288
|
+
console.log("For quality and privacy, persona creation requires interactive multi-angle photo upload");
|
|
289
|
+
console.log("and face consistency training, which is exclusively supported in the Web Studio.");
|
|
290
|
+
console.log(`\nš Create your persona at: ${pc.cyan("https://thumbnailgpt.com/studio")}\n`);
|
|
291
|
+
});
|
|
292
|
+
// 8. MCP Server Mode
|
|
249
293
|
program
|
|
250
294
|
.command("mcp")
|
|
251
295
|
.description("Run the ThumbnailGPT MCP server via standard I/O (stdio)")
|
package/dist/mcp.js
CHANGED
|
@@ -14,7 +14,7 @@ export async function runMcpServer() {
|
|
|
14
14
|
const client = new ThumbnailGPTClient(apiKey);
|
|
15
15
|
const server = new Server({
|
|
16
16
|
name: "thumbnailgpt-mcp",
|
|
17
|
-
version: "1.0.
|
|
17
|
+
version: "1.0.3",
|
|
18
18
|
}, {
|
|
19
19
|
capabilities: {
|
|
20
20
|
tools: {},
|
|
@@ -63,10 +63,22 @@ export async function runMcpServer() {
|
|
|
63
63
|
type: "string",
|
|
64
64
|
description: "Base image URL for inpainting / iterations.",
|
|
65
65
|
},
|
|
66
|
+
personaId: {
|
|
67
|
+
type: "string",
|
|
68
|
+
description: "Optional UUID of an active Creator Persona to feature in the thumbnail. Get available persona IDs with thumbnailgpt_get_personas.",
|
|
69
|
+
},
|
|
66
70
|
},
|
|
67
71
|
required: ["prompt"],
|
|
68
72
|
},
|
|
69
73
|
},
|
|
74
|
+
{
|
|
75
|
+
name: "thumbnailgpt_get_personas",
|
|
76
|
+
description: "Retrieve active, ready-to-use creator personas. Returns safe identifiers (id, name, created_at). Image URLs, internal storage paths, and failed personas are strictly omitted for privacy and security. (Note: New personas can only be trained in the Web UI at https://thumbnailgpt.com/studio).",
|
|
77
|
+
inputSchema: {
|
|
78
|
+
type: "object",
|
|
79
|
+
properties: {},
|
|
80
|
+
},
|
|
81
|
+
},
|
|
70
82
|
{
|
|
71
83
|
name: "thumbnailgpt_get_credits",
|
|
72
84
|
description: "Retrieve current ThumbnailGPT available credit balance, subscription status, and resolution cost tiers.",
|
|
@@ -119,6 +131,21 @@ export async function runMcpServer() {
|
|
|
119
131
|
],
|
|
120
132
|
};
|
|
121
133
|
}
|
|
134
|
+
if (name === "thumbnailgpt_get_personas") {
|
|
135
|
+
const personas = await client.getPersonas();
|
|
136
|
+
return {
|
|
137
|
+
content: [
|
|
138
|
+
{
|
|
139
|
+
type: "text",
|
|
140
|
+
text: JSON.stringify({
|
|
141
|
+
personas,
|
|
142
|
+
count: personas.length,
|
|
143
|
+
guidance: "Pass the persona 'id' to thumbnailgpt_generate as 'personaId' to render the creator in the thumbnail. To create new personas, use the Web UI at https://thumbnailgpt.com/studio.",
|
|
144
|
+
}, null, 2),
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
};
|
|
148
|
+
}
|
|
122
149
|
if (name === "thumbnailgpt_generate") {
|
|
123
150
|
const prompt = args?.prompt || "";
|
|
124
151
|
const chatId = args?.chatId;
|
|
@@ -127,6 +154,7 @@ export async function runMcpServer() {
|
|
|
127
154
|
const referenceImages = args?.referenceImages;
|
|
128
155
|
const youtubeUrl = args?.youtubeUrl;
|
|
129
156
|
const baseImage = args?.baseImage;
|
|
157
|
+
const personaId = args?.personaId;
|
|
130
158
|
const result = await client.generateAndWait({
|
|
131
159
|
prompt,
|
|
132
160
|
chatId,
|
|
@@ -135,6 +163,7 @@ export async function runMcpServer() {
|
|
|
135
163
|
referenceImages,
|
|
136
164
|
youtubeUrl,
|
|
137
165
|
baseImage,
|
|
166
|
+
personaId,
|
|
138
167
|
});
|
|
139
168
|
if (!result.success || !result.imageUrl) {
|
|
140
169
|
return {
|
package/dist/types.d.ts
CHANGED