New:Socket for Asana Is Now Available.Learn more
Sign In

@glbforge/mcp

Package Overview
Dependencies
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@glbforge/mcp - npm Package Compare versions

Comparing version
0.3.1
to
0.4.0
+48
-4
dist/index.js

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

import { analyze, createNodeIO, extrudeImage, getProfile, optimize, PROFILES, stripMaterials, toStl, } from '@glbforge/core';
import { MeshyClient } from '@glbforge/meshy';
import { FAL_MODELS, FalClient, MeshyClient } from '@glbforge/meshy';
// --- .env (never overrides real env vars, never logs values) ---

@@ -60,3 +60,3 @@ try {

});
const server = new McpServer({ name: 'glbforge', version: '0.3.0' });
const server = new McpServer({ name: 'glbforge', version: '0.4.0' });
server.registerTool('list_profiles', {

@@ -161,2 +161,4 @@ description: 'List the available web performance budget profiles (triangle/texture/file-size caps).',

.describe('Puffy-sticker dome height in meters (e.g. 0.04); supersedes bevel'),
emboss: z.number().optional()
.describe('Luminance micro-relief in meters — bright artwork rises (try depth*0.15)'),
preset: z.enum(['enamel', 'chrome', 'neon', 'acrylic', 'rubber']).optional()

@@ -170,3 +172,3 @@ .describe('Material preset for the forged piece'),

},
}, async ({ path, out, mode, threshold, width, depth, bevel, bevelSegments, layers, pillow, preset, simplify, texture, color, metallic, roughness }) => {
}, async ({ path, out, mode, threshold, width, depth, bevel, bevelSegments, layers, pillow, emboss, preset, simplify, texture, color, metallic, roughness }) => {
const bytes = await readFile(path);

@@ -178,3 +180,3 @@ const rgba = color

const { doc, stats } = await extrudeImage(new Uint8Array(bytes), {
mode, threshold, width, depth, bevel, bevelSegments, layers, pillow, preset, simplify,
mode, threshold, width, depth, bevel, bevelSegments, layers, pillow, emboss, preset, simplify,
texture, color: rgba, metallic, roughness,

@@ -211,2 +213,44 @@ });

});
server.registerTool('generate_image_to_3d', {
description: 'True volumetric 3D from a single image via open models on fal.ai GPU inference ' +
'(needs FAL_KEY): hunyuan (Hunyuan3D-2, highest quality), trellis (balanced), ' +
'triposr (fastest). Cheaper than Meshy for most subjects; use Meshy for the richest ' +
'PBR texturing. Returns a request id — poll generation_status, then download.',
inputSchema: {
image: z.string().describe('Local path or http(s) URL of the source image'),
model: z.enum(['hunyuan', 'trellis', 'triposr']).default('hunyuan'),
},
}, async ({ image, model }) => {
const client = new FalClient();
let imageUrl = image;
if (!/^https?:\/\//.test(image)) {
const ext = image.toLowerCase().split('.').pop();
const mime = { png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg', webp: 'image/webp' }[ext ?? ''];
if (!mime)
throw new Error(`Unsupported image extension ".${ext}"`);
imageUrl = `data:${mime};base64,${(await readFile(image)).toString('base64')}`;
}
const requestId = await client.submit(FAL_MODELS[model], imageUrl);
return json({ requestId, model, hint: 'Poll generation_status; typical time 1-3 minutes.' });
});
server.registerTool('generation_status', {
description: 'Check an open-model generation (from generate_image_to_3d); when COMPLETED, pass download=true with an out path to save the GLB.',
inputSchema: {
requestId: z.string(),
model: z.enum(['hunyuan', 'trellis', 'triposr']),
download: z.boolean().default(false),
out: z.string().optional().describe('Absolute output path for the .glb when downloading'),
},
}, async ({ requestId, model, download, out }) => {
const client = new FalClient();
const st = await client.status(FAL_MODELS[model], requestId);
if (!download || st.status !== 'COMPLETED') {
return json({ status: st.status, queuePosition: st.queuePosition });
}
if (!out)
throw new Error('pass "out" to download the finished model');
const bytes = await client.downloadGlb(await client.resultGlbUrl(FAL_MODELS[model], requestId));
await writeFile(out, bytes);
return json({ status: 'COMPLETED', out, bytes: bytes.byteLength });
});
server.registerTool('meshy_create_task', {

@@ -213,0 +257,0 @@ description: 'Start a Meshy generation task (needs MESHY_API_KEY). kind "image-to-3d" takes a ' +

+3
-3
{
"name": "@glbforge/mcp",
"version": "0.3.1",
"version": "0.4.0",
"type": "module",

@@ -12,4 +12,4 @@ "bin": {

"zod": "^3.23.0",
"@glbforge/core": "^0.3.0",
"@glbforge/meshy": "^0.3.0"
"@glbforge/core": "^0.4.0",
"@glbforge/meshy": "^0.4.0"
},

@@ -16,0 +16,0 @@ "devDependencies": {