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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. 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.9",
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.9";
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
- structuredContent: { title: "Parts", gallery: (data.frames || []).flatMap((f) => frameItems(f, args.id)).slice(0, MAX_GALLERY) },
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
- structuredContent: { title: "Pixel art", gallery: data.image ? [{ kind: "image", url: `data:image/png;base64,${data.image}`, label: "Pixelated" }] : [] },
771
- };
773
+ }, data.image ? [{ kind: "image", url: `data:image/png;base64,${data.image}`, label: "Pixelated" }] : [], "Pixel art");
772
774
  })
773
775
  );
774
776