create_fixture_instance
Add a new lighting fixture to a project by specifying manufacturer, model, DMX universe, and channel details. Streamline fixture configuration and organization for efficient lighting design workflows.
Instructions
Create a new fixture instance in a project with manufacturer/model details
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| channelAssignment | No | How to assign channels: auto=find next available, manual=use provided startChannel, suggest=recommend placement | auto |
| description | No | Description of where this fixture is placed or its purpose | |
| manufacturer | Yes | Fixture manufacturer (e.g., "Chauvet", "Martin", "ETC") | |
| mode | No | Specific mode if the fixture has multiple modes | |
| model | Yes | Fixture model name | |
| name | Yes | Name for this fixture instance | |
| projectId | Yes | Project ID to add fixture to | |
| startChannel | No | Starting DMX channel (1-512). If not provided, will auto-assign | |
| tags | No | Tags for organization (e.g., ["front", "wash", "blue"]) | |
| universe | No | DMX universe number (typically 1-4) |
Input Schema (JSON Schema)
{
"properties": {
"channelAssignment": {
"default": "auto",
"description": "How to assign channels: auto=find next available, manual=use provided startChannel, suggest=recommend placement",
"enum": [
"auto",
"manual",
"suggest"
],
"type": "string"
},
"description": {
"description": "Description of where this fixture is placed or its purpose",
"type": "string"
},
"manufacturer": {
"description": "Fixture manufacturer (e.g., \"Chauvet\", \"Martin\", \"ETC\")",
"type": "string"
},
"mode": {
"description": "Specific mode if the fixture has multiple modes",
"type": "string"
},
"model": {
"description": "Fixture model name",
"type": "string"
},
"name": {
"description": "Name for this fixture instance",
"type": "string"
},
"projectId": {
"description": "Project ID to add fixture to",
"type": "string"
},
"startChannel": {
"description": "Starting DMX channel (1-512). If not provided, will auto-assign",
"type": "number"
},
"tags": {
"default": [],
"description": "Tags for organization (e.g., [\"front\", \"wash\", \"blue\"])",
"items": {
"type": "string"
},
"type": "array"
},
"universe": {
"default": 1,
"description": "DMX universe number (typically 1-4)",
"type": "number"
}
},
"required": [
"projectId",
"name",
"manufacturer",
"model"
],
"type": "object"
}
Implementation Reference
- src/tools/fixture-tools.ts:674-833 (handler)Main execution handler for the 'create_fixture_instance' MCP tool. Validates input with Zod schema, verifies project existence, finds or intelligently creates fixture definition, handles DMX channel assignment (auto/suggest/manual), and calls GraphQL mutation to create the fixture instance.async createFixtureInstance( args: z.infer<typeof CreateFixtureInstanceSchema>, ) { const { projectId, name, description, manufacturer, model, mode, universe, startChannel, tags, channelAssignment, } = CreateFixtureInstanceSchema.parse(args); try { // Get project to verify it exists const project = await this.graphqlClient.getProject(projectId); if (!project) { throw new Error(`Project with ID ${projectId} not found`); } // Find or create fixture definition const definitions = await this.graphqlClient.getFixtureDefinitions(); let fixtureDefinition = definitions.find( (d) => d.manufacturer.toLowerCase() === manufacturer.toLowerCase() && d.model.toLowerCase() === model.toLowerCase(), ); if (!fixtureDefinition) { // Create fixture definition based on intelligent analysis const { channels, fixtureType } = this.createIntelligentFixtureChannels(mode, model, manufacturer); fixtureDefinition = await this.graphqlClient.createFixtureDefinition({ manufacturer, model, type: fixtureType, channels, modes: mode ? [{ name: mode, channelCount: channels.length }] : [], }); } if (!fixtureDefinition) { throw new Error("Failed to create or find fixture definition"); } // Check if mode is required when multiple modes are available if (fixtureDefinition.modes.length > 1 && !mode) { const availableModes = fixtureDefinition.modes.map(m => ({ name: m.name, channelCount: m.channelCount, shortName: m.shortName })); throw new Error( `Mode selection required. This fixture (${manufacturer} ${model}) has ${fixtureDefinition.modes.length} available modes. ` + `Please specify a mode from: ${availableModes.map(m => `"${m.name}" (${m.channelCount} channels)`).join(', ')}. ` + `Available modes: ${JSON.stringify(availableModes, null, 2)}` ); } // Find the specific mode if requested let selectedMode: any = null; if (mode && fixtureDefinition.modes.length > 0) { selectedMode = fixtureDefinition.modes.find( (m) => m.name.toLowerCase().includes(mode.toLowerCase()) || mode.toLowerCase().includes(m.name.toLowerCase()), ); if (!selectedMode) { // If exact match not found, try to find by channel count const modeChannelCount = parseInt(mode.match(/\d+/)?.[0] || "0"); if (modeChannelCount > 0) { selectedMode = fixtureDefinition.modes.find( (m) => m.channelCount === modeChannelCount, ); } } // If mode was specified but no match found, provide helpful error if (!selectedMode && fixtureDefinition.modes.length > 0) { const availableModes = fixtureDefinition.modes.map(m => ({ name: m.name, channelCount: m.channelCount, shortName: m.shortName })); throw new Error( `Invalid mode "${mode}" for fixture ${manufacturer} ${model}. ` + `Available modes: ${availableModes.map(m => `"${m.name}" (${m.channelCount} channels)`).join(', ')}. ` + `Mode details: ${JSON.stringify(availableModes, null, 2)}` ); } } // Handle channel assignment let finalStartChannel = startChannel; if (channelAssignment === "auto" && !startChannel) { finalStartChannel = await this.findNextAvailableChannel( projectId, universe, fixtureDefinition.channels.length, ); } else if (channelAssignment === "suggest") { const suggestion = await this.suggestChannelAssignment({ projectId, fixtureSpecs: [{ name, manufacturer, model, mode }], universe, startingChannel: startChannel || 1, groupingStrategy: "sequential", }); finalStartChannel = suggestion.assignments[0]?.startChannel || 1; } if (!finalStartChannel) { finalStartChannel = 1; } // Create fixture instance const fixture = await this.graphqlClient.createFixtureInstance({ projectId, name, description, definitionId: fixtureDefinition.id, modeId: selectedMode?.id, universe, startChannel: finalStartChannel || 1, tags, }); return { fixture: { id: fixture.id, name: fixture.name, description: fixture.description, manufacturer: fixtureDefinition.manufacturer, model: fixtureDefinition.model, mode: selectedMode?.name || mode || "Default", modeId: selectedMode?.id, requestedMode: mode, universe: fixture.universe, startChannel: fixture.startChannel, channelCount: selectedMode?.channelCount || fixtureDefinition.channels.length, tags: fixture.tags, }, channelAssignment: { method: channelAssignment, assignedChannel: finalStartChannel, channelRange: `${finalStartChannel}-${finalStartChannel + (selectedMode?.channelCount || fixtureDefinition.channels.length) - 1}`, }, message: `Successfully created fixture "${name}" in project`, }; } catch (error) { throw new Error(`Failed to create fixture instance: ${error}`); } }
- src/tools/fixture-tools.ts:40-75 (schema)Zod input validation schema for create_fixture_instance tool, defining all parameters with descriptions, defaults, and types. This schema is used for parsing args and generates the JSON schema exposed in MCP tool registration.const CreateFixtureInstanceSchema = z.object({ projectId: z.string().describe("Project ID to add fixture to"), name: z.string().describe("Name for this fixture instance"), description: z .string() .optional() .describe("Description of where this fixture is placed or its purpose"), manufacturer: z .string() .describe('Fixture manufacturer (e.g., "Chauvet", "Martin", "ETC")'), model: z.string().describe("Fixture model name"), mode: z .string() .optional() .describe("Specific mode if the fixture has multiple modes"), universe: z .number() .default(1) .describe("DMX universe number (typically 1-4)"), startChannel: z .number() .optional() .describe( "Starting DMX channel (1-512). If not provided, will auto-assign", ), tags: z .array(z.string()) .default([]) .describe('Tags for organization (e.g., ["front", "wash", "blue"])'), channelAssignment: z .enum(["auto", "manual", "suggest"]) .default("auto") .describe( "How to assign channels: auto=find next available, manual=use provided startChannel, suggest=recommend placement", ), });
- src/index.ts:335-395 (registration)MCP tool registration in listTools handler: defines the 'create_fixture_instance' tool name, description, and inputSchema (JSON Schema equivalent of Zod schema) advertised to MCP clients.name: "create_fixture_instance", description: "Create a new fixture instance in a project with manufacturer/model details", inputSchema: { type: "object", properties: { projectId: { type: "string", description: "Project ID to add fixture to", }, name: { type: "string", description: "Name for this fixture instance", }, description: { type: "string", description: "Description of where this fixture is placed or its purpose", }, manufacturer: { type: "string", description: 'Fixture manufacturer (e.g., "Chauvet", "Martin", "ETC")', }, model: { type: "string", description: "Fixture model name", }, mode: { type: "string", description: "Specific mode if the fixture has multiple modes", }, universe: { type: "number", default: 1, description: "DMX universe number (typically 1-4)", }, startChannel: { type: "number", description: "Starting DMX channel (1-512). If not provided, will auto-assign", }, tags: { type: "array", items: { type: "string" }, default: [], description: 'Tags for organization (e.g., ["front", "wash", "blue"])', }, channelAssignment: { type: "string", enum: ["auto", "manual", "suggest"], default: "auto", description: "How to assign channels: auto=find next available, manual=use provided startChannel, suggest=recommend placement", }, }, required: ["projectId", "name", "manufacturer", "model"], }, },
- src/index.ts:1940-1952 (registration)Dispatch handler in callTool request: routes 'create_fixture_instance' calls to FixtureTools.createFixtureInstance method and returns JSON-stringified result as MCP content.case "create_fixture_instance": return { content: [ { type: "text", text: JSON.stringify( await this.fixtureTools.createFixtureInstance(args as any), null, 2, ), }, ], };