pixellab-forge-mcp 1.3.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"job-log.js","sourceRoot":"","sources":["../src/job-log.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * MCP Prompts — discoverable prompt templates that appear as slash commands
3
+ * in clients like Claude Desktop, Cursor, etc.
4
+ */
5
+ export interface PromptDef {
6
+ name: string;
7
+ description: string;
8
+ arguments?: Array<{
9
+ name: string;
10
+ description: string;
11
+ required?: boolean;
12
+ }>;
13
+ messages: (args: Record<string, string>) => Array<{
14
+ role: "user" | "assistant";
15
+ content: {
16
+ type: "text";
17
+ text: string;
18
+ };
19
+ }>;
20
+ }
21
+ export declare const prompts: PromptDef[];
@@ -0,0 +1,290 @@
1
+ /**
2
+ * MCP Prompts — discoverable prompt templates that appear as slash commands
3
+ * in clients like Claude Desktop, Cursor, etc.
4
+ */
5
+ export const prompts = [
6
+ {
7
+ name: "pf:help",
8
+ description: "Overview of PixelLab Forge tools and how to use them",
9
+ messages: () => [
10
+ {
11
+ role: "user",
12
+ content: {
13
+ type: "text",
14
+ text: `Give me a quick overview of what PixelLab Forge can do and how to use it. Cover:
15
+ - The main generation tools (generate_image, generate_with_style, generate_ui) and when to use each
16
+ - Characters & objects (persistent vs one-off)
17
+ - Animation options
18
+ - Tilesets (standard vs pro)
19
+ - Editing & inpainting
20
+ - Image operations (resize, remove background, convert to pixel art)
21
+ - Key tips (sizes, seeds, backgrounds)
22
+ Keep it concise — bullet points, not paragraphs.`,
23
+ },
24
+ },
25
+ ],
26
+ },
27
+ {
28
+ name: "pf:character",
29
+ description: "Create a pixel art character with directional views and optional animation",
30
+ arguments: [
31
+ {
32
+ name: "description",
33
+ description: "Character description (e.g. 'a knight in silver armor')",
34
+ required: true,
35
+ },
36
+ {
37
+ name: "size",
38
+ description: "Sprite size in pixels (e.g. '64x64'). Max 128x128.",
39
+ required: false,
40
+ },
41
+ ],
42
+ messages: (args) => {
43
+ const size = args.size || "48x48";
44
+ return [
45
+ {
46
+ role: "user",
47
+ content: {
48
+ type: "text",
49
+ text: `Create a pixel art character: ${args.description}
50
+
51
+ Requirements:
52
+ - Size: ${size}
53
+ - Create with 4 directional views (N/S/E/W) using create_character_4dir
54
+ - Use low top-down view
55
+ - After creation, ask me which animations I'd like to add (e.g. walking, fireball, breathing-idle)
56
+ - Show me what animation templates are available`,
57
+ },
58
+ },
59
+ ];
60
+ },
61
+ },
62
+ {
63
+ name: "pf:tileset",
64
+ description: "Create a tileset for a top-down or platformer game",
65
+ arguments: [
66
+ {
67
+ name: "style",
68
+ description: "Game style (e.g. 'medieval fantasy', 'sci-fi', 'nature')",
69
+ required: true,
70
+ },
71
+ {
72
+ name: "type",
73
+ description: "Tileset type: 'topdown' (default) or 'sidescroller'",
74
+ required: false,
75
+ },
76
+ ],
77
+ messages: (args) => {
78
+ const type = args.type || "topdown";
79
+ const isSide = type === "sidescroller";
80
+ return [
81
+ {
82
+ role: "user",
83
+ content: {
84
+ type: "text",
85
+ text: `Create a ${isSide ? "sidescroller" : "top-down"} tileset with a ${args.style} theme.
86
+
87
+ Requirements:
88
+ - Tile size: 32x32
89
+ - ${isSide
90
+ ? "Use create_tileset_sidescroller. Design a platform terrain with a decorative transition layer."
91
+ : "Use create_tileset. Design a lower terrain, upper terrain, and transition between them. Set transition_size to 0.5."}
92
+ - After creating the first tileset, suggest 2-3 complementary terrain combinations I could add to build out a full map.`,
93
+ },
94
+ },
95
+ ];
96
+ },
97
+ },
98
+ {
99
+ name: "pf:tiles",
100
+ description: "Create hex, isometric, or octagon tiles for strategy or isometric games",
101
+ arguments: [
102
+ {
103
+ name: "description",
104
+ description: "What the tiles should look like (e.g. 'grass plains', 'stone dungeon floor')",
105
+ required: true,
106
+ },
107
+ {
108
+ name: "shape",
109
+ description: "Tile shape: hex, hex_pointy, isometric, octagon, square_topdown",
110
+ required: false,
111
+ },
112
+ {
113
+ name: "count",
114
+ description: "Number of tile variations (1-16)",
115
+ required: false,
116
+ },
117
+ ],
118
+ messages: (args) => {
119
+ const shape = args.shape || "isometric";
120
+ const count = args.count || "4";
121
+ return [
122
+ {
123
+ role: "user",
124
+ content: {
125
+ type: "text",
126
+ text: `Create ${count} ${shape} tiles: ${args.description}
127
+
128
+ Requirements:
129
+ - Use create_tiles_pro
130
+ - Tile type: ${shape}
131
+ - Tile size: 32px
132
+ - Number of tiles: ${count}
133
+ - Number each tile description for best results (e.g. "1). lush grass 2). sparse grass 3). grass with flowers")
134
+ - Use low top-down view
135
+ - After generation, ask if I want more variations or different terrain types to match.`,
136
+ },
137
+ },
138
+ ];
139
+ },
140
+ },
141
+ {
142
+ name: "pf:sprite",
143
+ description: "Generate a pixel art sprite from a description",
144
+ arguments: [
145
+ {
146
+ name: "description",
147
+ description: "What to generate (e.g. 'a fire sword', 'a treasure chest')",
148
+ required: true,
149
+ },
150
+ {
151
+ name: "size",
152
+ description: "Image size (e.g. '64x64', '128x128')",
153
+ required: false,
154
+ },
155
+ ],
156
+ messages: (args) => {
157
+ const size = args.size || "64x64";
158
+ return [
159
+ {
160
+ role: "user",
161
+ content: {
162
+ type: "text",
163
+ text: `Generate a pixel art sprite: ${args.description}
164
+
165
+ Requirements:
166
+ - Size: ${size}
167
+ - Use generate_image (the Pro endpoint)
168
+ - No background (transparent)
169
+ - Show me the saved file path after generation
170
+ - If I want variations, I can ask for different seeds`,
171
+ },
172
+ },
173
+ ];
174
+ },
175
+ },
176
+ {
177
+ name: "pf:ui",
178
+ description: "Generate pixel art UI elements for a game",
179
+ arguments: [
180
+ {
181
+ name: "description",
182
+ description: "UI element description (e.g. 'medieval stone button', 'sci-fi health bar')",
183
+ required: true,
184
+ },
185
+ {
186
+ name: "palette",
187
+ description: "Color palette (e.g. 'brown and gold', 'blue and silver')",
188
+ required: false,
189
+ },
190
+ ],
191
+ messages: (args) => {
192
+ const palette = args.palette ? `\n- Color palette: ${args.palette}` : "";
193
+ return [
194
+ {
195
+ role: "user",
196
+ content: {
197
+ type: "text",
198
+ text: `Generate a pixel art UI element: ${args.description}
199
+
200
+ Requirements:
201
+ - Use generate_ui
202
+ - Size: 256x256 (adjust aspect ratio if needed for the element type)
203
+ - No background${palette}
204
+ - After generation, suggest related UI elements that would complement this one (e.g. if I made a button, suggest matching panels, icons, health bars).`,
205
+ },
206
+ },
207
+ ];
208
+ },
209
+ },
210
+ {
211
+ name: "pf:animate",
212
+ description: "Animate an existing sprite or character image",
213
+ arguments: [
214
+ {
215
+ name: "action",
216
+ description: "Animation action (e.g. 'walking east', 'swinging a sword', 'idle breathing')",
217
+ required: true,
218
+ },
219
+ ],
220
+ messages: (args) => [
221
+ {
222
+ role: "user",
223
+ content: {
224
+ type: "text",
225
+ text: `I want to animate a sprite: ${args.action}
226
+
227
+ Help me choose the right approach:
228
+ 1. If I have a persistent character ID → use animate_character with a template
229
+ 2. If I have a single sprite image → use animate_with_text_v2
230
+ 3. If I have start and end keyframes → use animate_with_text_v3
231
+ 4. If I need precise pose control → use estimate_skeleton then animate_with_skeleton
232
+
233
+ Ask me what I'm starting with (character ID, single image, or keyframes) and then proceed with the right tool.`,
234
+ },
235
+ },
236
+ ],
237
+ },
238
+ {
239
+ name: "pf:style",
240
+ description: "Generate new art matching the style of existing sprites",
241
+ arguments: [
242
+ {
243
+ name: "description",
244
+ description: "What to generate (e.g. 'a treasure chest', 'a healing potion')",
245
+ required: true,
246
+ },
247
+ ],
248
+ messages: (args) => [
249
+ {
250
+ role: "user",
251
+ content: {
252
+ type: "text",
253
+ text: `Generate pixel art matching my existing art style: ${args.description}
254
+
255
+ I'll provide 1-4 reference images. Use generate_with_style to match their pixel density, outline weight, shading approach, and color palette.
256
+
257
+ Please ask me to provide the style reference images, then generate the new art at the same size as the references.`,
258
+ },
259
+ },
260
+ ],
261
+ },
262
+ {
263
+ name: "pf:edit",
264
+ description: "Edit or modify an existing pixel art image",
265
+ arguments: [
266
+ {
267
+ name: "edit",
268
+ description: "What to change (e.g. 'make the armor gold', 'add a cape', 'replace sword with axe')",
269
+ required: true,
270
+ },
271
+ ],
272
+ messages: (args) => [
273
+ {
274
+ role: "user",
275
+ content: {
276
+ type: "text",
277
+ text: `I want to edit a sprite: ${args.edit}
278
+
279
+ Help me choose the right approach:
280
+ 1. Full image edit (change the whole thing) → use edit_image
281
+ 2. Edit a specific region (need a mask) → use inpaint_v3
282
+ 3. Batch edit multiple sprites consistently → use edit_images
283
+
284
+ Ask me to provide the image(s), then proceed with the simplest approach that works.`,
285
+ },
286
+ },
287
+ ],
288
+ },
289
+ ];
290
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export interface ExtractedImage {
2
+ base64: string;
3
+ filePath: string;
4
+ mimeType: string;
5
+ }
6
+ /**
7
+ * Walk through an API response, find all base64 image data,
8
+ * save them to disk, and return the file paths + raw base64 for MCP image blocks.
9
+ * Also strips base64 data from the result to keep the JSON response small.
10
+ */
11
+ export declare function extractAndSaveImages(result: unknown, toolName: string): {
12
+ images: ExtractedImage[];
13
+ result: unknown;
14
+ };
@@ -0,0 +1,242 @@
1
+ import { writeFileSync, mkdirSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { deflateSync } from "node:zlib";
4
+ const OUTPUT_DIR = join(process.cwd(), "pixellab-forge-output");
5
+ function ensureOutputDir() {
6
+ mkdirSync(OUTPUT_DIR, { recursive: true });
7
+ }
8
+ /** Generate a filename from the tool name and a short ID */
9
+ function makeFilename(toolName, index, id) {
10
+ const timestamp = Date.now();
11
+ const suffix = id ? `_${id.slice(0, 8)}` : "";
12
+ const indexStr = index > 0 ? `_${index}` : "";
13
+ return `${toolName}${suffix}${indexStr}_${timestamp}.png`;
14
+ }
15
+ /** Encode raw RGBA pixel data into a PNG file buffer */
16
+ function rgbaToPng(rgba, width, height) {
17
+ // Each row gets a filter byte (0 = None) prepended
18
+ const raw = Buffer.alloc(height * (1 + width * 4));
19
+ for (let y = 0; y < height; y++) {
20
+ const rowOffset = y * (1 + width * 4);
21
+ raw[rowOffset] = 0; // filter: None
22
+ rgba.copy(raw, rowOffset + 1, y * width * 4, (y + 1) * width * 4);
23
+ }
24
+ const signature = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
25
+ function crc32(buf) {
26
+ let c = 0xffffffff;
27
+ for (let i = 0; i < buf.length; i++) {
28
+ c ^= buf[i];
29
+ for (let j = 0; j < 8; j++)
30
+ c = (c >>> 1) ^ (c & 1 ? 0xedb88320 : 0);
31
+ }
32
+ return (c ^ 0xffffffff) >>> 0;
33
+ }
34
+ function chunk(type, data) {
35
+ const typeAndData = Buffer.concat([Buffer.from(type, "ascii"), data]);
36
+ const len = Buffer.alloc(4);
37
+ len.writeUInt32BE(data.length);
38
+ const crc = Buffer.alloc(4);
39
+ crc.writeUInt32BE(crc32(typeAndData));
40
+ return Buffer.concat([len, typeAndData, crc]);
41
+ }
42
+ // IHDR: width, height, bit depth 8, color type 6 (RGBA)
43
+ const ihdr = Buffer.alloc(13);
44
+ ihdr.writeUInt32BE(width, 0);
45
+ ihdr.writeUInt32BE(height, 4);
46
+ ihdr[8] = 8; // bit depth
47
+ ihdr[9] = 6; // color type: RGBA
48
+ ihdr[10] = 0; // compression
49
+ ihdr[11] = 0; // filter
50
+ ihdr[12] = 0; // interlace
51
+ const compressed = deflateSync(raw);
52
+ return Buffer.concat([
53
+ signature,
54
+ chunk("IHDR", ihdr),
55
+ chunk("IDAT", compressed),
56
+ chunk("IEND", Buffer.alloc(0)),
57
+ ]);
58
+ }
59
+ /** Decode a base64 image string, handling data URI prefix if present */
60
+ function decodeBase64(data) {
61
+ const raw = data.replace(/^data:image\/\w+;base64,/, "");
62
+ return Buffer.from(raw, "base64");
63
+ }
64
+ /** Save a single base64 image and return the file path */
65
+ function saveImage(base64, toolName, index, id) {
66
+ ensureOutputDir();
67
+ const filename = makeFilename(toolName, index, id);
68
+ const filepath = join(OUTPUT_DIR, filename);
69
+ writeFileSync(filepath, decodeBase64(base64));
70
+ return filepath;
71
+ }
72
+ /** Strip data URI prefix and any whitespace from base64 string so it's clean for the Claude API */
73
+ function cleanBase64(data) {
74
+ return data.replace(/^data:image\/\w+;base64,/, "").replace(/\s/g, "");
75
+ }
76
+ /** Validate that a base64 string decodes to a non-empty buffer with a valid image header */
77
+ function isValidImageBase64(b64) {
78
+ try {
79
+ const buf = Buffer.from(b64, "base64");
80
+ if (buf.length < 8)
81
+ return false;
82
+ // Check for PNG magic bytes (89 50 4E 47)
83
+ const isPng = buf[0] === 0x89 && buf[1] === 0x50 && buf[2] === 0x4e && buf[3] === 0x47;
84
+ // Check for JPEG magic bytes (FF D8 FF)
85
+ const isJpeg = buf[0] === 0xff && buf[1] === 0xd8 && buf[2] === 0xff;
86
+ // Check for WebP (RIFF....WEBP)
87
+ const isWebp = buf[0] === 0x52 && buf[1] === 0x49 && buf[2] === 0x46 && buf[3] === 0x46;
88
+ // Check for GIF (GIF8)
89
+ const isGif = buf[0] === 0x47 && buf[1] === 0x49 && buf[2] === 0x46 && buf[3] === 0x38;
90
+ return isPng || isJpeg || isWebp || isGif;
91
+ }
92
+ catch {
93
+ return false;
94
+ }
95
+ }
96
+ /** Detect MIME type from base64 data */
97
+ function detectMimeType(b64) {
98
+ try {
99
+ const buf = Buffer.from(b64, "base64");
100
+ if (buf.length >= 4) {
101
+ if (buf[0] === 0xff && buf[1] === 0xd8 && buf[2] === 0xff)
102
+ return "image/jpeg";
103
+ if (buf[0] === 0x47 && buf[1] === 0x49 && buf[2] === 0x46)
104
+ return "image/gif";
105
+ if (buf[0] === 0x52 && buf[1] === 0x49 && buf[2] === 0x46 && buf[3] === 0x46)
106
+ return "image/webp";
107
+ }
108
+ }
109
+ catch { }
110
+ return "image/png";
111
+ }
112
+ /**
113
+ * Walk through an API response, find all base64 image data,
114
+ * save them to disk, and return the file paths + raw base64 for MCP image blocks.
115
+ * Also strips base64 data from the result to keep the JSON response small.
116
+ */
117
+ export function extractAndSaveImages(result, toolName) {
118
+ const images = [];
119
+ /** Save image to disk and add to inline list only if it has valid image headers */
120
+ function addImage(b64, toolLabel, index, width, height) {
121
+ // For rgba_bytes, convert to PNG base64 for both saving and inline display
122
+ let pngBase64 = b64;
123
+ if (width && height) {
124
+ const buf = Buffer.from(b64, "base64");
125
+ if (buf.length === width * height * 4) {
126
+ pngBase64 = rgbaToPng(buf, width, height).toString("base64");
127
+ }
128
+ }
129
+ const path = saveImage(pngBase64, toolLabel, index);
130
+ if (isValidImageBase64(pngBase64)) {
131
+ images.push({ base64: pngBase64, filePath: path, mimeType: "image/png" });
132
+ }
133
+ else {
134
+ process.stderr.write(`[pixellab-forge-mcp] Warning: saved ${path} but base64 has no valid image header, skipping inline display\n`);
135
+ images.push({ base64: "", filePath: path, mimeType: "image/png" });
136
+ }
137
+ }
138
+ if (!result || typeof result !== "object") {
139
+ return { images, result };
140
+ }
141
+ const data = result;
142
+ /** Extract width/height from an image object (for rgba_bytes conversion) */
143
+ function getDims(obj) {
144
+ if (obj && typeof obj === "object") {
145
+ const o = obj;
146
+ const w = typeof o.width === "number" ? o.width : undefined;
147
+ const h = typeof o.height === "number" ? o.height : undefined;
148
+ return { w, h };
149
+ }
150
+ return {};
151
+ }
152
+ // Single image response: { image: { type: "base64", base64: "...", format: "png" } }
153
+ if (isImageObj(data.image)) {
154
+ const b64 = cleanBase64(data.image.base64);
155
+ const { w, h } = getDims(data.image);
156
+ addImage(b64, toolName, 0, w, h);
157
+ stripBase64(data.image);
158
+ }
159
+ // Single image as direct base64 string: { image: "base64..." }
160
+ if (typeof data.image === "string" && data.image.length > 100) {
161
+ const b64 = cleanBase64(data.image);
162
+ addImage(b64, toolName, 0);
163
+ data.image = "[base64 image data stripped]";
164
+ }
165
+ // Multiple images: { images: [{ type: "base64", base64: "..." }, ...] }
166
+ if (Array.isArray(data.images)) {
167
+ data.images.forEach((img, i) => {
168
+ if (isImageObj(img)) {
169
+ const b64 = cleanBase64(img.base64);
170
+ const { w, h } = getDims(img);
171
+ addImage(b64, toolName, i, w, h);
172
+ stripBase64(img);
173
+ }
174
+ else if (typeof img === "string" && img.length > 100) {
175
+ const b64 = cleanBase64(img);
176
+ addImage(b64, toolName, i);
177
+ data.images[i] = "[base64 image data stripped]";
178
+ }
179
+ });
180
+ }
181
+ // Frames response: { frames: [{ type: "base64", base64: "..." }, ...] }
182
+ if (Array.isArray(data.frames)) {
183
+ data.frames.forEach((frame, i) => {
184
+ if (isImageObj(frame)) {
185
+ const b64 = cleanBase64(frame.base64);
186
+ const { w, h } = getDims(frame);
187
+ addImage(b64, toolName, i, w, h);
188
+ stripBase64(frame);
189
+ }
190
+ });
191
+ }
192
+ // Character directions: { directions: { south: { image: {...} }, ... } }
193
+ if (data.directions && typeof data.directions === "object") {
194
+ const dirs = data.directions;
195
+ let i = 0;
196
+ for (const [dir, value] of Object.entries(dirs)) {
197
+ if (value && typeof value === "object") {
198
+ const dirData = value;
199
+ if (isImageObj(dirData.image)) {
200
+ const b64 = cleanBase64(dirData.image.base64);
201
+ const { w, h } = getDims(dirData.image);
202
+ addImage(b64, `${toolName}_${dir}`, i, w, h);
203
+ stripBase64(dirData.image);
204
+ i++;
205
+ }
206
+ }
207
+ }
208
+ }
209
+ // Tileset tiles: { tiles: [{ image: {...} }, ...] }
210
+ if (Array.isArray(data.tiles)) {
211
+ data.tiles.forEach((tile, i) => {
212
+ if (tile && typeof tile === "object") {
213
+ const t = tile;
214
+ if (isImageObj(t.image)) {
215
+ const b64 = cleanBase64(t.image.base64);
216
+ const { w, h } = getDims(t.image);
217
+ addImage(b64, toolName, i, w, h);
218
+ stripBase64(t.image);
219
+ }
220
+ }
221
+ });
222
+ }
223
+ // Nested in last_response (from job polling)
224
+ if (data.last_response && typeof data.last_response === "object") {
225
+ const nested = extractAndSaveImages(data.last_response, toolName);
226
+ images.push(...nested.images);
227
+ }
228
+ return { images, result };
229
+ }
230
+ function isImageObj(val) {
231
+ return (val !== null &&
232
+ typeof val === "object" &&
233
+ typeof val.base64 === "string" &&
234
+ val.base64.length > 100);
235
+ }
236
+ /** Replace base64 data in-place with a placeholder to keep JSON responses small */
237
+ function stripBase64(obj) {
238
+ if (obj && typeof obj === "object") {
239
+ obj.base64 = "[stripped]";
240
+ }
241
+ }
242
+ //# sourceMappingURL=save-images.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"save-images.js","sourceRoot":"","sources":["../src/save-images.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { PixelLabClient } from "./api-client.js";
2
+ export interface ToolDef {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: Record<string, unknown>;
6
+ handler: (client: PixelLabClient, args: Record<string, unknown>) => Promise<unknown>;
7
+ }
8
+ export declare const tools: ToolDef[];