@gripforgeai/mcp 0.1.25 → 0.1.26
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/dist/attach-options.js +11 -0
- package/dist/server.js +16 -1
- package/package.json +1 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export function createPropGripSchema(factory = z) {
|
|
3
|
+
const Z = factory;
|
|
4
|
+
const vector = Z.tuple([Z.number().finite(), Z.number().finite(), Z.number().finite()]);
|
|
5
|
+
return Z.object({
|
|
6
|
+
position: vector.describe('Grip point in the prop scene local coordinates'),
|
|
7
|
+
axis: vector.describe('Handle direction / shield top (+Y of the grip frame)'),
|
|
8
|
+
normal: vector.describe('Blade flat / outward shield face (+Z of the grip frame)'),
|
|
9
|
+
}).describe('Exact prop grip frame; overrides geometric guesses. A gf_grip locator can supply the same frame.');
|
|
10
|
+
}
|
|
11
|
+
export const propGripSchema = createPropGripSchema();
|
package/dist/server.js
CHANGED
|
@@ -12,6 +12,7 @@ import { basename, dirname, extname, join, resolve } from 'node:path';
|
|
|
12
12
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
13
13
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
14
14
|
import { z } from 'zod';
|
|
15
|
+
import { propGripSchema } from './attach-options.js';
|
|
15
16
|
import { registerVfxProjectTools } from './vfx-project-tools.js';
|
|
16
17
|
import { registerSceneTools } from './scene-tools.js';
|
|
17
18
|
import { registerServerTools } from './server-tools.js';
|
|
@@ -84,6 +85,10 @@ server.tool('gripforge_attach', 'Attach a prop (sword, shield, gun, staff/scythe
|
|
|
84
85
|
style: z.enum(['melee', 'gun', 'shield', 'staff']).optional().describe('Grip style (default: guessed from the filename)'),
|
|
85
86
|
hand: z.enum(['right', 'left']).optional().describe('Hand side (default right)'),
|
|
86
87
|
height_ratio: z.number().min(0.05).max(1.5).optional().describe('Prop size as a fraction of body height'),
|
|
88
|
+
prop_grip: propGripSchema.optional(),
|
|
89
|
+
style_2: z.enum(['melee', 'gun', 'shield', 'staff']).optional().describe('Style of the second held item'),
|
|
90
|
+
height_ratio_2: z.number().min(0.05).max(1.5).optional(),
|
|
91
|
+
prop_grip_2: propGripSchema.optional(),
|
|
87
92
|
fist: z.number().min(0).max(1).optional().describe('Fist closing amount, 0 open → 1 closed (default 1)'),
|
|
88
93
|
grip_offset: z
|
|
89
94
|
.array(z.number())
|
|
@@ -100,7 +105,7 @@ server.tool('gripforge_attach', 'Attach a prop (sword, shield, gun, staff/scythe
|
|
|
100
105
|
.describe('Bake character + closed fist + prop into one attached.glb (requires out_dir; .glb/.gltf inputs only). ' +
|
|
101
106
|
'Use this for mitten-hand rigs: the closed fist cannot travel in the bind JSON.'),
|
|
102
107
|
out_dir: z.string().optional().describe('Write bind.json + engine snippets into this folder'),
|
|
103
|
-
}, async ({ character_path, prop_path, character_id, attach_id, prop_id, prop_id_2, prop_path_2, style, hand, height_ratio, fist, grip_offset, ai_refine, export_glb, out_dir }) => {
|
|
108
|
+
}, async ({ character_path, prop_path, character_id, attach_id, prop_id, prop_id_2, prop_path_2, style, hand, height_ratio, prop_grip, style_2, height_ratio_2, prop_grip_2, fist, grip_offset, ai_refine, export_glb, out_dir }) => {
|
|
104
109
|
if (!API_KEY) {
|
|
105
110
|
return err('GRIPFORGE_API_KEY missing. Create a free account at ' +
|
|
106
111
|
API_URL +
|
|
@@ -148,6 +153,8 @@ server.tool('gripforge_attach', 'Attach a prop (sword, shield, gun, staff/scythe
|
|
|
148
153
|
form.append('hand', hand);
|
|
149
154
|
if (height_ratio != null)
|
|
150
155
|
form.append('ratio', String(height_ratio));
|
|
156
|
+
if (prop_grip)
|
|
157
|
+
form.append('prop_grip', JSON.stringify(prop_grip));
|
|
151
158
|
if (fist != null)
|
|
152
159
|
form.append('fist', String(fist));
|
|
153
160
|
if (grip_offset)
|
|
@@ -195,6 +202,12 @@ server.tool('gripforge_attach', 'Attach a prop (sword, shield, gun, staff/scythe
|
|
|
195
202
|
form2.append('export', 'glb');
|
|
196
203
|
form2.append('fingers', '1');
|
|
197
204
|
form2.append('hand', hand === 'left' ? 'right' : 'left');
|
|
205
|
+
if (style_2)
|
|
206
|
+
form2.append('style', style_2);
|
|
207
|
+
if (height_ratio_2 != null)
|
|
208
|
+
form2.append('ratio', String(height_ratio_2));
|
|
209
|
+
if (prop_grip_2)
|
|
210
|
+
form2.append('prop_grip', JSON.stringify(prop_grip_2));
|
|
198
211
|
const res2 = await fetch(`${API_URL}/api/v1/attach`, {
|
|
199
212
|
method: 'POST',
|
|
200
213
|
headers: apiHeaders(),
|
|
@@ -1300,6 +1313,8 @@ server.tool('gripforge_loadout', 'Build a multi-weapon character in ONE call: at
|
|
|
1300
1313
|
prop_id: z.string(),
|
|
1301
1314
|
hand: z.enum(['left', 'right']).optional(),
|
|
1302
1315
|
style: z.enum(['melee', 'gun', 'shield', 'staff']).optional(),
|
|
1316
|
+
height_ratio: z.number().min(.05).max(1.5).optional(),
|
|
1317
|
+
prop_grip: propGripSchema.optional(),
|
|
1303
1318
|
})))
|
|
1304
1319
|
.describe('set name → props to hold in that set'),
|
|
1305
1320
|
default_set: z.string().optional().describe('Set visible by default (first set otherwise)'),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gripforgeai/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.26",
|
|
4
4
|
"description": "The tools your AI needs to make your games. Turn prompts into production-ready game assets \u2014 animated characters with their weapons attached, seamless textures, terrain, VFX, HUDs \u2014 and playable game kits Unity, Godot, Unreal or Three.js can load.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|