Skip to main content
Glama
bbernstein

LacyLights MCP Server

by bbernstein

get_project_details

Retrieve comprehensive details of a specific project by providing its ID, enabling users to manage and analyze theatrical lighting designs effectively within the LacyLights MCP Server.

Instructions

Get detailed information about a specific project

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
projectIdYesProject ID to get details for

Implementation Reference

  • Main tool handler: Fetches full project details including fixtures (grouped by universe with channel ranges), scenes summary, and cue lists summary. Organizes and sorts fixture data for easy consumption.
    async getProjectDetails(args: z.infer<typeof GetProjectDetailsSchema>) {
      const { projectId } = GetProjectDetailsSchema.parse(args);
    
      try {
        const project = await this.graphqlClient.getProject(projectId);
    
        if (!project) {
          throw new Error(`Project with ID ${projectId} not found`);
        }
    
        // Organize fixtures by universe
        const fixturesByUniverse = project.fixtures.reduce((acc, fixture) => {
          if (!acc[fixture.universe]) {
            acc[fixture.universe] = [];
          }
          acc[fixture.universe].push(fixture);
          return acc;
        }, {} as Record<number, typeof project.fixtures>);
    
        // Sort fixtures within each universe by start channel
        Object.values(fixturesByUniverse).forEach(fixtures => {
          fixtures.sort((a, b) => a.startChannel - b.startChannel);
        });
    
        return {
          project: {
            id: project.id,
            name: project.name,
            description: project.description,
            createdAt: project.createdAt,
            updatedAt: project.updatedAt
          },
          fixtures: {
            total: project.fixtures.length,
            byUniverse: Object.entries(fixturesByUniverse).map(([universe, fixtures]) => ({
              universe: parseInt(universe),
              fixtureCount: fixtures.length,
              channelRanges: this.calculateChannelRanges(fixtures),
              fixtures: fixtures.map(f => ({
                id: f.id,
                name: f.name,
                type: f.type,
                manufacturer: f.manufacturer,
                model: f.model,
                mode: f.modeName,
                channels: `${f.startChannel}-${f.startChannel + f.channelCount - 1}`,
                tags: f.tags
              }))
            }))
          },
          scenes: {
            total: project.scenes.length,
            list: project.scenes.map(s => ({
              id: s.id,
              name: s.name,
              description: s.description,
              fixtureCount: s.fixtureValues?.length || 0
            }))
          },
          cueLists: {
            total: project.cueLists.length,
            list: project.cueLists.map(cl => ({
              id: cl.id,
              name: cl.name,
              description: cl.description,
              cueCount: cl.cues?.length || 0
            }))
          }
        };
      } catch (error) {
        throw new Error(`Failed to get project details: ${error}`);
      }
    }
  • Zod input validation schema for the getProjectDetails handler.
    const GetProjectDetailsSchema = z.object({
      projectId: z.string().describe('Project ID to get details for')
    });
  • src/index.ts:1832-1844 (registration)
    MCP CallToolRequestHandler switch case that delegates execution to projectTools.getProjectDetails
    case "get_project_details":
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(
              await this.projectTools.getProjectDetails(args as any),
              null,
              2,
            ),
          },
        ],
      };
  • src/index.ts:139-152 (registration)
    Tool metadata and input schema registration in ListToolsRequestHandler response.
    {
      name: "get_project_details",
      description: "Get detailed information about a specific project including all fixtures, scenes, and cue lists. This returns a lot of data and should only be used when you need comprehensive project information.",
      inputSchema: {
        type: "object",
        properties: {
          projectId: {
            type: "string",
            description: "Project ID to get details for",
          },
        },
        required: ["projectId"],
      },
    },
  • Helper function to compute merged DMX channel ranges for fixtures within a universe, used in getProjectDetails for fixture summaries.
    private calculateChannelRanges(fixtures: any[]): string {
      if (fixtures.length === 0) return 'None';
    
      const ranges: Array<{ start: number; end: number }> = [];
    
      fixtures.forEach(fixture => {
        const start = fixture.startChannel;
        const channelCount = fixture.channelCount;
        const end = start + channelCount - 1;
    
        // Check if this range can be merged with the last one
        if (ranges.length > 0) {
          const lastRange = ranges[ranges.length - 1];
          if (start <= lastRange.end + 1) {
            // Extend the last range
            lastRange.end = Math.max(lastRange.end, end);
            return;
          }
        }
    
        // Add new range
        ranges.push({ start, end });
      });
    
      return ranges.map(r => r.start === r.end ? `${r.start}` : `${r.start}-${r.end}`).join(', ');
    }

Latest Blog Posts

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/bbernstein/lacylights-mcp'

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