Skip to main content
Glama

3D-MCP

by team-plask
entity.ts6.65 kB
import { z } from "zod"; /** * Base entity definition all entities will extend */ export const _BaseEntity = z.object({ id: z.string().describe("Unique identifier"), name: z.string().describe("Display name"), metadata: z .record(z.string(), z.any()) .optional() .describe("Additional tool-specific metadata"), }); /** * Standard operation response */ export const _OperationResponse = z.object({ success: z.boolean().describe("Operation success status"), }); /** * Data types for tensor values, aligned with glTF */ export const _TensorType = z.enum([ "SCALAR", // Single value "VEC2", // 2D vector "VEC3", // 3D vector "VEC4", // 4D vector "MAT2", // 2×2 matrix "MAT3", // 3×3 matrix "MAT4", // 4×4 matrix "QUAT", // Quaternion ]); /** * Helper to create tensor validators with consistent typing */ const createTensor = <T extends z.infer<typeof _TensorType>>( length: number, typeName: T ) => z .array(z.number()) .length(length) .describe(`${typeName} tensor with ${length} components`); /** * Type-specific tensor validators */ export const _Tensor = { SCALAR: z.number(), VEC2: createTensor(2, "VEC2"), VEC3: createTensor(3, "VEC3"), VEC4: createTensor(4, "VEC4"), QUAT: createTensor(4, "QUAT"), MAT2: createTensor(4, "MAT2"), MAT3: createTensor(9, "MAT3"), MAT4: createTensor(16, "MAT4"), // Common value union for flexible APIs any: z .array(z.number()) .describe("Generic tensor value (scalar, vector, matrix, or object)"), }; /** * Common transformable object properties */ export const _Transformable = z.object({ position: z.array(z.number()).describe("Position in 3D space [x, y, z]"), rotation: z.array(z.number()).describe("Rotation in 3D space [x, y, z, w]"), scale: z.array(z.number()).describe("Scale factors in 3D space [x, y, z]"), }); /** * Visual properties common to renderable entities */ export const _VisualProperties = z.object({ visible: z.boolean().default(true).describe("Visibility state"), locked: z.boolean().default(false).describe("Editing lock state"), castShadow: z .boolean() .default(true) .describe("Whether the object casts shadows"), receiveShadow: z .boolean() .default(true) .describe("Whether the object receives shadows"), renderOrder: z.number().int().default(0).describe("Render sorting order"), }); /** * Hierarchical object properties */ export const _Hierarchical = z.object({ parentId: z.string().optional().describe("Parent object ID"), childIds: z.array(z.string()).default([]).describe("Child object IDs"), }); /** * Bounds - Axis-aligned bounding box */ export const _Bounds = z.object({ min: _Tensor.VEC3.describe("Minimum point [x, y, z]"), max: _Tensor.VEC3.describe("Maximum point [x, y, z]"), center: _Tensor.VEC3.optional().describe("Center point [x, y, z]"), size: _Tensor.VEC3.optional().describe( "Size dimensions [width, height, depth]" ), }); /** * Interpolation types for animation and curves */ export const _InterpolationType = z.enum([ "linear", // Linear interpolation "step", // Discrete step function "bezier", // Cubic Bezier curve "hermite", // Hermite spline "catmull", // Catmull-Rom spline "constant", // No interpolation (hold value) ]); /** * Extrapolation behaviors for curves */ export const _ExtrapolationType = z.enum([ "constant", // Hold last/first value "linear", // Continue linear trend "cycle", // Repeat from beginning "cycleWithOffset", // Repeat with offset "oscillate", // Ping-pong back and forth ]); /** * Node base definition for scene graph */ export const _NodeBase = _BaseEntity.extend({ ..._Transformable.shape, ..._Hierarchical.shape, }); /** * Constraint - Restriction on object movement (common across domains) */ export const Constraint = _BaseEntity.extend({ type: z .enum([ "point", "aim", "orientation", "parent", "pole", "ik", "spring", "path", "scaleTo", "lookAt", ]) .describe("Constraint type"), sourceId: z.string().describe("Source object ID (the one that drives)"), targetId: z.string().describe("Target object ID (the one being constrained)"), influence: z.number().min(0).max(1).describe("Constraint influence strength"), maintainOffset: z.boolean().describe("Whether to maintain initial offset"), skipRotation: z .array(z.enum(["x", "y", "z"])) .optional() .describe("Rotation axes to skip"), skipTranslation: z .array(z.enum(["x", "y", "z"])) .optional() .describe("Translation axes to skip"), skipScale: z .array(z.enum(["x", "y", "z"])) .optional() .describe("Scale axes to skip"), space: z .enum(["world", "local", "custom"]) .describe("Space in which constraint operates"), customSpaceId: z .string() .optional() .describe("Custom space reference object ID"), active: z.boolean().describe("Whether constraint is active"), }); /** * BlendShape - Per-vertex mesh deformation (used in both modeling and animation) */ export const BlendShape = _BaseEntity.extend({ meshId: z.string().describe("ID of the target mesh"), weight: z .number() .min(0) .max(1) .default(0) .describe("Current blend shape weight"), deltas: z .array( z.object({ vertexIndex: z.number().int().nonnegative().describe("Vertex index"), positionDelta: _Tensor.VEC3.describe("Position offset"), normalDelta: _Tensor.VEC3.optional().describe("Normal vector offset"), tangentDelta: _Tensor.VEC3.optional().describe("Tangent vector offset"), }) ) .describe("Per-vertex deformation deltas"), combineMethod: z .enum(["average", "additive"]) .default("additive") .describe("How this shape combines with others"), }); /** * Joint - Base joint/bone definition for skeletal systems */ export const Joint = _NodeBase.extend({ length: z.number().nonnegative().default(1).describe("Length of the joint"), }); /** * Pose - A stored set of transforms for joints/bones */ export const Pose = _BaseEntity.extend({ transforms: z .record(z.string(), _Tensor.MAT4) .describe("Transforms by joint/bone ID (ID -> matrix)"), isBindPose: z .boolean() .default(false) .describe("Whether this is a bind/rest pose"), }); export const CoreEntities = { _BaseEntity, _OperationResponse, _TensorType, _Tensor, _Transformable, _VisualProperties, _Hierarchical, _Bounds, _InterpolationType, _ExtrapolationType, _NodeBase, Constraint, BlendShape, Joint, Pose, } as const;

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/team-plask/3d-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server