Skip to main content
Glama
bbernstein

LacyLights MCP Server

by bbernstein

analyze_script

Analyze theatrical scripts to extract lighting cues and generate scene suggestions, enhancing lighting design for LacyLights MCP Server.

Instructions

Analyze a theatrical script to extract lighting-relevant information

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
extractLightingCuesNoExtract specific lighting cues from the script
scriptTextYesThe theatrical script text to analyze
suggestScenesNoGenerate scene suggestions based on analysis

Implementation Reference

  • Main execution logic for the 'analyze_script' tool: parses input using Zod schema, calls RAG service for script analysis, extracts lighting cues if requested, generates scene suggestions if requested, and returns structured analysis.
    async analyzeScript(args: z.infer<typeof AnalyzeScriptSchema>) {
      const { scriptText, extractLightingCues, suggestScenes } = AnalyzeScriptSchema.parse(args);
    
      try {
        // Analyze script using RAG service
        const scriptAnalysis = await this.ragService.analyzeScript(scriptText);
    
        const result: GenerateSceneResult = {
          analysis: scriptAnalysis,
          totalCues: scriptAnalysis.scenes.length,
          characters: scriptAnalysis.characters,
          overallMood: scriptAnalysis.overallMood,
          themes: scriptAnalysis.themes
        };
    
        if (extractLightingCues) {
          // Extract specific lighting cues from the analysis
          const lightingCues = scriptAnalysis.scenes.flatMap((scene, _index) => 
            scene.lightingCues.map(cue => ({
              sceneNumber: scene.sceneNumber,
              cue,
              context: scene.content.substring(0, 200) + '...',
              suggestedTiming: this.suggestCueTiming(cue, scene.mood)
            }))
          );
    
          result.lightingCues = lightingCues;
          result.totalCues = lightingCues.length;
        }
    
        if (suggestScenes) {
          // Generate scene suggestions based on script analysis
          const sceneTemplates = await Promise.all(
            scriptAnalysis.scenes.slice(0, 5).map(async (scene, _index) => {
              const recommendations = await this.ragService.generateLightingRecommendations(
                scene.content,
                scene.mood,
                ['LED_PAR', 'MOVING_HEAD'] // Default fixture types
              );
    
              return {
                sceneNumber: scene.sceneNumber,
                title: scene.title || `Scene ${scene.sceneNumber}`,
                mood: scene.mood,
                timeOfDay: scene.timeOfDay,
                location: scene.location,
                suggestedLighting: {
                  colorPalette: recommendations.colorSuggestions,
                  intensity: this.mapIntensityLevel(recommendations.intensityLevels),
                  focusAreas: recommendations.focusAreas,
                  reasoning: recommendations.reasoning
                },
                estimatedFixtureCount: this.estimateFixtureNeeds(recommendations)
              };
            })
          );
    
          result.sceneTemplates = sceneTemplates;
        }
    
        return result;
      } catch (error) {
        throw new Error(`Failed to analyze script: ${error}`);
      }
  • Zod schema defining input parameters for the analyze_script tool: scriptText (required), extractLightingCues and suggestScenes (optional booleans with defaults). Used for validation in handler.
    const AnalyzeScriptSchema = z.object({
      scriptText: z.string(),
      extractLightingCues: z.boolean().default(true),
      suggestScenes: z.boolean().default(true)
    });
  • src/index.ts:861-884 (registration)
    Tool registration in ListToolsRequestSchema handler: defines name 'analyze_script', description, and inputSchema matching AnalyzeScriptSchema.
      name: "analyze_script",
      description:
        "Analyze a theatrical script to extract lighting-relevant information",
      inputSchema: {
        type: "object",
        properties: {
          scriptText: {
            type: "string",
            description: "The theatrical script text to analyze",
          },
          extractLightingCues: {
            type: "boolean",
            default: true,
            description: "Extract specific lighting cues from the script",
          },
          suggestScenes: {
            type: "boolean",
            default: true,
            description: "Generate scene suggestions based on analysis",
          },
        },
        required: ["scriptText"],
      },
    },
  • src/index.ts:2098-2110 (registration)
    Dispatch handler in CallToolRequestSchema: routes 'analyze_script' calls to sceneTools.analyzeScript method.
    case "analyze_script":
      return {
        content: [
          {
            type: "text",
            text: JSON.stringify(
              await this.sceneTools.analyzeScript(args as any),
              null,
              2,
            ),
          },
        ],
      };
  • Core RAG service method analyzeScript that performs GPT-4 analysis on script text to extract scenes, moods, characters, lighting cues, etc., returning ScriptAnalysis object. Called by the tool handler.
      async analyzeScript(scriptText: string): Promise<ScriptAnalysis> {
        const prompt = `
    Analyze this theatrical script and extract lighting-relevant information. Return a JSON object with the following structure:
    
    {
      "scenes": [
        {
          "sceneNumber": "string",
          "title": "string (optional)",
          "content": "string (excerpt)",
          "mood": "string (e.g., tense, romantic, mysterious)",
          "characters": ["string"],
          "stageDirections": ["string"],
          "lightingCues": ["string"],
          "timeOfDay": "string (optional)",
          "location": "string (optional)"
        }
      ],
      "characters": ["string"],
      "settings": ["string"],
      "overallMood": "string",
      "themes": ["string"]
    }
    
    Script text:
    ${scriptText}
    
    Focus on:
    - Mood and atmosphere descriptions
    - Time of day and location changes
    - Stage directions that imply lighting
    - Character entrances and emotional beats
    - Explicit lighting cues in the text
    `;
    
        const response = await this.openai.chat.completions.create({
          model: 'gpt-4',
          messages: [{ role: 'user', content: prompt }],
          temperature: 0.3
        });
    
        const content = response.choices[0].message.content || '{}';
        try {
          return JSON.parse(content);
        } catch (_error) {
          // If JSON parsing fails, try to extract JSON from the response
          const jsonMatch = content.match(/\{[\s\S]*\}/);
          if (jsonMatch) {
            try {
              return JSON.parse(jsonMatch[0]);
            } catch (_e) {
              // If still fails, return a fallback structure
              return {
                scenes: [],
                characters: [],
                settings: [],
                overallMood: 'unknown',
                themes: []
              };
            }
          }
          return {
            scenes: [],
            characters: [],
            settings: [],
            overallMood: 'unknown',
            themes: []
          };
        }
      }

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