voidless-mcp 1.6.9 → 1.6.10
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/package.json +1 -1
- package/tools.js +10 -8
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "voidless-mcp",
|
|
3
3
|
"mcpName": "dev.voidless/voidless",
|
|
4
|
-
"version": "1.6.
|
|
4
|
+
"version": "1.6.10",
|
|
5
5
|
"description": "MCP server for Voidless: generate game sprites, animations, sound, music, video and 3D models",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "Voidless Dev Inc. <contact@voidless.dev>",
|
package/tools.js
CHANGED
|
@@ -25,7 +25,7 @@ import { Agent, setGlobalDispatcher } from "undici";
|
|
|
25
25
|
// server does.
|
|
26
26
|
setGlobalDispatcher(new Agent({ headersTimeout: 0, bodyTimeout: 0, connectTimeout: 30_000 }));
|
|
27
27
|
|
|
28
|
-
export const VERSION = "1.6.
|
|
28
|
+
export const VERSION = "1.6.10";
|
|
29
29
|
const BASE_URL = process.env.VOIDLESS_API_URL || "https://api.voidless.dev";
|
|
30
30
|
const CDN_URL = "https://cdn.voidless.dev";
|
|
31
31
|
// Where asset links point. Results link to the asset's page in the app rather than to raw GIFs: the
|
|
@@ -277,9 +277,13 @@ export function createVoidlessServer(API_KEY) {
|
|
|
277
277
|
return item ? [item] : [];
|
|
278
278
|
}
|
|
279
279
|
const MAX_GALLERY = 48;
|
|
280
|
+
// Clients that read structuredContent hand the MODEL that object instead of the text content
|
|
281
|
+
// (Claude Code does), so it carries the same text as `summary`: without it the model saw only the
|
|
282
|
+
// gallery and told users "the tool didn't report its cost" and that it had one frame to look at.
|
|
283
|
+
const textOf = (result) => (result.content || []).filter((c) => c.type === "text").map((c) => c.text).join("\n");
|
|
280
284
|
const withGallery = (result, items, title) => ({
|
|
281
285
|
...result,
|
|
282
|
-
structuredContent: { title, gallery: items.filter(Boolean).slice(0, MAX_GALLERY) },
|
|
286
|
+
structuredContent: { title, summary: textOf(result), gallery: items.filter(Boolean).slice(0, MAX_GALLERY) },
|
|
283
287
|
});
|
|
284
288
|
|
|
285
289
|
// Read by clients as the server's standing instructions (MCP `instructions`).
|
|
@@ -721,15 +725,14 @@ export function createVoidlessServer(API_KEY) {
|
|
|
721
725
|
// The ids returned here are off by (parts - 1): the server numbers from the last appended
|
|
722
726
|
// frame. Point at get_asset instead of printing ids that would misdirect a follow-up call.
|
|
723
727
|
const names = (data.frames || []).map((f) => f.name).filter(Boolean);
|
|
724
|
-
return {
|
|
728
|
+
return withGallery({
|
|
725
729
|
content: [
|
|
726
730
|
{
|
|
727
731
|
type: "text",
|
|
728
732
|
text: `Extracted ${names.length} parts from asset ${args.id}: ${names.join(", ")}.\n${money(data)}\nUse get_asset ${args.id} for their frame ids and image keys.`,
|
|
729
733
|
},
|
|
730
734
|
],
|
|
731
|
-
|
|
732
|
-
};
|
|
735
|
+
}, (data.frames || []).flatMap((f) => frameItems(f, args.id)), "Parts");
|
|
733
736
|
})
|
|
734
737
|
);
|
|
735
738
|
|
|
@@ -762,13 +765,12 @@ export function createVoidlessServer(API_KEY) {
|
|
|
762
765
|
writeTool("Pixelate image"),
|
|
763
766
|
tool(async ({ image, ...rest }) => {
|
|
764
767
|
const data = await apiPost("/pixelate/image", { image: String(image).replace(/^data:[^,]*,/, ""), ...rest });
|
|
765
|
-
return {
|
|
768
|
+
return withGallery({
|
|
766
769
|
content: [
|
|
767
770
|
{ type: "text", text: money(data) || "Pixelated." },
|
|
768
771
|
{ type: "image", data: data.image, mimeType: "image/png" },
|
|
769
772
|
],
|
|
770
|
-
|
|
771
|
-
};
|
|
773
|
+
}, data.image ? [{ kind: "image", url: `data:image/png;base64,${data.image}`, label: "Pixelated" }] : [], "Pixel art");
|
|
772
774
|
})
|
|
773
775
|
);
|
|
774
776
|
|