🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@picoberry/mcp-server

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@picoberry/mcp-server - npm Package Compare versions

Comparing version
0.1.2
to
0.1.3
+47
-21
dist/index.js

@@ -52,3 +52,3 @@ #!/usr/bin/env node

const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const server = new McpServer({ name: "picoberry", version: "0.1.0" });
const server = new McpServer({ name: "picoberry", version: "0.1.3" });
/* ------------------------------ Discovery ------------------------------ */

@@ -113,22 +113,48 @@ server.tool("list_models", "List available generation engines/models and their credit cost for a category. " +

})).data));
server.tool("generate_3d_from_image", "Generate a 3D model (GLB) from a single image (async). Provide EITHER `image_url` " +
"(any public http/https image, or a prior generation's files.image) OR `image_path` " +
"(a local file, uploaded directly — no hosting needed). Then wait_for_asset and read " +
"files.model. Costs credits — see list_models(category='3d').", {
image_url: z.string().url().optional(),
server.tool("generate_3d_from_image", "Generate a 3D model (GLB) from one image, or from 2–4 views of the same subject " +
"(multi-view → higher-fidelity geometry), async. Single: `image_url` (any public " +
"http/https image, or a prior generation's files.image) OR `image_path` (a local file, " +
"uploaded directly — no hosting needed). Multi-view: `image_urls` OR `image_paths`, " +
"ordered [front, left, back, right] (2–4 views). Multi-view is only supported by tripo*, " +
"meshy6, and hunyuan-3.x engines — others return 400. Local files win over URLs. Then " +
"wait_for_asset and read files.model. Costs credits — see list_models(category='3d').", {
image_url: z.string().url().optional().describe("single hosted image URL"),
image_path: z
.string()
.optional()
.describe("absolute path to a local image file (≤20MB)"),
.describe("absolute path to a single local image file (≤20MB)"),
image_urls: z
.array(z.string().url())
.min(2)
.max(4)
.optional()
.describe("multi-view: 2–4 hosted image URLs, ordered [front, left, back, right]"),
image_paths: z
.array(z.string())
.min(2)
.max(4)
.optional()
.describe("multi-view: 2–4 local image file paths (each ≤20MB), ordered [front, left, back, right]"),
engine: z.string().optional(),
polycount: z.number().int().positive().optional(),
texture: z.boolean().default(true),
}, async ({ image_url, image_path, engine, polycount, texture }) => run(async () => {
if (!image_url && !image_path) {
throw new PicoBerryError("Provide either image_url or image_path.");
}, async ({ image_url, image_path, image_urls, image_paths, engine, polycount, texture }) => run(async () => {
// Resolve source images with the same precedence as the backend facade:
// local files > hosted URLs, and multi-view arrays > single fields.
const paths = image_paths?.length
? image_paths
: image_path
? [image_path]
: [];
const urls = image_urls?.length ? image_urls : image_url ? [image_url] : [];
if (!paths.length && !urls.length) {
throw new PicoBerryError("Provide one of: image_url / image_path (single), or image_urls / image_paths (2–4 views).");
}
if (image_path) {
const buf = await readFile(image_path);
// Local files → multipart. Single uses the `image` part, multi-view `images`.
if (paths.length) {
const form = new FormData();
form.append("image", new Blob([buf]), basename(image_path));
const field = paths.length > 1 ? "images" : "image";
for (const p of paths) {
form.append(field, new Blob([await readFile(p)]), basename(p));
}
if (engine)

@@ -141,10 +167,10 @@ form.append("engine", engine);

}
return (await client.request("POST", "/v1/models/from-image", {
json: {
imageUrl: image_url,
...(engine ? { engine } : {}),
...(polycount ? { polycount } : {}),
texture,
},
})).data;
// Hosted URLs → JSON. Single uses `imageUrl`, multi-view `imageUrls`.
const json = {
...(urls.length > 1 ? { imageUrls: urls } : { imageUrl: urls[0] }),
...(engine ? { engine } : {}),
...(polycount ? { polycount } : {}),
texture,
};
return (await client.request("POST", "/v1/models/from-image", { json })).data;
}));

@@ -151,0 +177,0 @@ /* --------------------------- Post-processing --------------------------- */

{
"name": "@picoberry/mcp-server",
"version": "0.1.2",
"version": "0.1.3",
"description": "PicoBerry MCP server — generate game-ready 3D models, images, and animations from any MCP client. Several 3D and image engines behind one API (query list_models for the live set); a thin wrapper over the PicoBerry /v1 API.",

@@ -5,0 +5,0 @@ "mcpName": "io.github.UModeler/picoberry-mcp",

@@ -1,3 +0,7 @@

# PicoBerry MCP Server
<p align="center">
<img src=".github/logo.png" alt="PicoBerry" width="96" height="96">
</p>
<h1 align="center">PicoBerry MCP Server</h1>
Generate **game-ready 3D models, images, and animations** from any MCP client —

@@ -61,3 +65,3 @@ Claude Code, Cursor, Claude Desktop, Cline — with no HTTP glue. A thin wrapper

| `generate_3d_from_text` | Text → 3D model (GLB). |
| `generate_3d_from_image` | Image → 3D model. Pass `image_url` or a local `image_path`. |
| `generate_3d_from_image` | Image → 3D model. Single: `image_url` or local `image_path`. Multi-view (2–4 views, higher fidelity): `image_urls` or `image_paths`, ordered [front, left, back, right] — tripo\*/meshy6/hunyuan-3.x only. |
| `remesh` | Retopologize an existing 3D asset → new asset. |

@@ -64,0 +68,0 @@ | `texture` | Re-texture (PBR) an existing 3D asset → new asset. |