Skip to main content
Glama

Get Key Light Position (Spherical Coordinates)

get_key_light_position_spherical

Retrieve the key light's current spherical coordinates relative to the camera. Query before making relative light adjustments to maintain accuracy.

Instructions

Get the current key light position in camera-centric spherical coordinates. Query this before relative position changes (e.g., "rotate light 10 degrees") to ensure accuracy. For absolute changes, you may use recently queried state from context if no manual interactions occurred.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • server.js:1114-1162 (registration)
    Registration of the 'get_key_light_position_spherical' tool via mcpServer.registerTool(). Includes schema definition (empty inputSchema) and the async handler that queries state and returns the key light position.
    mcpServer.registerTool(
      'get_key_light_position_spherical',
      {
        title: 'Get Key Light Position (Spherical Coordinates)',
        description: 'Get the current key light position in camera-centric spherical coordinates. ' +
          'Query this before relative position changes (e.g., "rotate light 10 degrees") to ensure accuracy. ' +
          'For absolute changes, you may use recently queried state from context if no manual interactions occurred.',
        inputSchema: {}
      },
      async () => {
        const sessionId = getCurrentSessionId();
        if (!sessionId) {
          return {
            content: [
              {
                type: 'text',
                text: 'Error: No active session found.'
              }
            ],
            isError: true
          };
        }
    
        try {
          const { state, metadata } = await getState(sessionId);
          const position = state.keyLight?.position || { azimuth: 0, elevation: 0, distance: 0 };
          const positionText = `azimuth ${position.azimuth}°, elevation ${position.elevation}°, distance ${position.distance}`;
          
          return {
            content: [
              {
                type: 'text',
                text: formatStateResponse(positionText, 'Key light position', sessionId, metadata)
              }
            ]
          };
        } catch (error) {
          return {
            content: [
              {
                type: 'text',
                text: `Error retrieving key light position: ${error.message}`
              }
            ],
            isError: true
          };
        }
      }
    );
  • The async handler function for get_key_light_position_spherical. It gets the current session ID, queries state from the browser via getState(), extracts keyLight.position (azimuth, elevation, distance), and returns the formatted response.
    async () => {
      const sessionId = getCurrentSessionId();
      if (!sessionId) {
        return {
          content: [
            {
              type: 'text',
              text: 'Error: No active session found.'
            }
          ],
          isError: true
        };
      }
    
      try {
        const { state, metadata } = await getState(sessionId);
        const position = state.keyLight?.position || { azimuth: 0, elevation: 0, distance: 0 };
        const positionText = `azimuth ${position.azimuth}°, elevation ${position.elevation}°, distance ${position.distance}`;
        
        return {
          content: [
            {
              type: 'text',
              text: formatStateResponse(positionText, 'Key light position', sessionId, metadata)
            }
          ]
        };
      } catch (error) {
        return {
          content: [
            {
              type: 'text',
              text: `Error retrieving key light position: ${error.message}`
            }
          ],
          isError: true
        };
      }
    }
  • Input schema for get_key_light_position_spherical - an empty object ({}) indicating no parameters are required.
    inputSchema: {}
  • queryFreshStateForManipulation helper - used to fetch fresh state from the browser before relative manipulations.
    // Helper function to query fresh state before relative manipulations
    async function queryFreshStateForManipulation(sessionId) {
      try {
        const { state } = await getState(sessionId);
        return state;
      } catch (error) {
        console.warn(`Failed to query fresh state before manipulation: ${error.message}`);
        return null;
      }
    }
  • getState and queryStateFromBrowser helpers - used by the handler to query the current 3D scene state (including light positions) from the connected browser client.
    // Query state from browser (with optional force refresh)
    async function queryStateFromBrowser(sessionId) {
      const requestId = generateRequestId();
      
      // Send request to browser
      const sent = sendToSession(sessionId, {
        type: 'requestState',
        requestId: requestId,
        forceRefresh: false
      });
      
      if (!sent) {
        throw new Error('Browser not connected');
      }
      
      // Wait for response
      return await waitForStateResponse(requestId);
    }
    
    // Get state (always queries browser, cache only as fallback)
    async function getState(sessionId) {
      let state;
      let source;
      let wasCached = false;
      
      // Always query browser for current state
      try {
        state = await queryStateFromBrowser(sessionId);
        source = 'fresh';
      } catch (error) {
        // If query fails, fall back to cache if available (browser may be disconnected)
        const cached = sessionStateCache.get(sessionId);
        if (cached) {
          console.warn(`Browser query failed for session ${sessionId}, returning cached state: ${error.message}`);
          state = cached.state;
          source = 'cache';
          wasCached = true;
        } else {
          // No cache available, throw error
          throw new Error(`Unable to retrieve state: ${error.message}. Browser may be disconnected.`);
        }
      }
      
      // Return state with metadata
      return {
        state,
        metadata: {
          source,
          wasCached,
          timestamp: new Date().toISOString()
        }
      };
    }
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries full burden for behavioral disclosure. While it implies a read-only operation, it does not explicitly state that it is non-destructive or describe any side effects, permissions, or rate limits. The advice about relative changes adds some behavioral context, but overall depth is limited.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences long, with the first directly stating the purpose and the second providing usage guidance. Every sentence is justified, and the information is front-loaded. No fluff or redundant content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple getter with no parameters and no output schema, the description covers purpose and usage context. It does not detail the return format (e.g., azimuth, elevation, radius), but 'camera-centric spherical coordinates' provides enough hint. It is mostly complete given the tool's simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has no parameters, so the base baseline is 4. The description does not explain parameters (none exist), so it adequately covers this dimension.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool retrieves the current key light position in camera-centric spherical coordinates. The verb 'Get' and the resource 'key light position in spherical coordinates' are specific, distinguishing it from sibling tools like get_fill_light_position_spherical.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly advises querying this tool before relative position changes (e.g., 'rotate light 10 degrees') to ensure accuracy, and mentions that for absolute changes, recently queried state from context may suffice if no manual interactions occurred. This provides clear when-to-use and when-not-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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/aidenlab/hello3dmcp-server'

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