Skip to main content
Glama

get-template-modifications

Retrieve available modifications for Orshot templates to customize image generation. Specify template ID and type to access editing options.

Instructions

Get available modifications for a specific template (works for both library and studio templates). For studio templates, you can use either ID or name.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
apiKeyNoOrshot API key for authentication (optional if set in environment)
templateIdYesThe ID or name of the template to get modifications for
templateTypeNoType of template (library, studio, or auto-detect)auto

Implementation Reference

  • src/index.ts:1257-1432 (registration)
    Registration of the get-template-modifications tool, including schema definition and inline handler function that detects template type and retrieves modifications from Orshot library or studio APIs.
    server.tool(
      "get-template-modifications",
      "Get available modifications for a specific template (works for both library and studio templates). For studio templates, you can use either ID or name.",
      {
        apiKey: z.string().optional().describe("Orshot API key for authentication (optional if set in environment)"),
        templateId: z.string().describe("The ID or name of the template to get modifications for"),
        templateType: z.enum(["library", "studio", "auto"]).default("auto").describe("Type of template (library, studio, or auto-detect)"),
      },
      async (args) => {
        const { apiKey, templateId, templateType } = args;
        const actualApiKey = apiKey || DEFAULT_API_KEY;
        
        if (!actualApiKey) {
          return {
            content: [
              {
                type: "text",
                text: "No API key provided. Please provide an API key parameter or set ORSHOT_API_KEY environment variable.",
              },
            ],
          };
        }
    
        try {
          let modifications: any[] = [];
          let detectedType: "library" | "studio" = templateType === "auto" ? "library" : templateType;
    
          if (templateType === "auto") {
            // Auto-detect template type
            const autoDetectedType = await getTemplateType(templateId, actualApiKey);
            if (!autoDetectedType) {
              return {
                content: [
                  {
                    type: "text",
                    text: `Template "${templateId}" not found in either library or studio templates.`,
                  },
                ],
              };
            }
            detectedType = autoDetectedType;
          }
    
          if (detectedType === "library") {
            // Get library template modifications
            try {
              // First try to get template details from the templates endpoint
              const templatesResponse = await fetch(`${ORSHOT_API_BASE}/v1/templates`, {
                method: "GET",
                headers: {
                  "Authorization": `Bearer ${actualApiKey}`,
                  "Content-Type": "application/json",
                },
              });
    
              if (templatesResponse.ok) {
                const templates = await templatesResponse.json();
                const templateArray = Array.isArray(templates) ? templates : [];
                const selectedTemplate = templateArray.find((template: any) => template.id === templateId);
    
                if (selectedTemplate && selectedTemplate.modifications) {
                  modifications = selectedTemplate.modifications;
                }
              }
    
              // Fallback to modifications endpoint if template doesn't have modifications
              if (modifications.length === 0) {
                const modResponse = await fetch(`${ORSHOT_API_BASE}/v1/templates/modifications?template_id=${templateId}`, {
                  method: "GET",
                  headers: {
                    "Authorization": `Bearer ${actualApiKey}`,
                    "Content-Type": "application/json",
                  },
                });
    
                if (modResponse.ok) {
                  const modData = await modResponse.json();
                  modifications = Array.isArray(modData) ? modData : [];
                }
              }
            } catch (error) {
              console.error("Error fetching library template modifications:", error);
            }
          } else if (detectedType === "studio") {
            // Get studio template modifications
            try {
              // First try to get template details from the templates endpoint
              const templatesResponse = await fetch(`${ORSHOT_API_BASE}/v1/studio/templates`, {
                method: "GET",
                headers: {
                  "Authorization": `Bearer ${actualApiKey}`,
                  "Content-Type": "application/json",
                },
              });
    
              if (templatesResponse.ok) {
                const templates = await templatesResponse.json();
                const templatesArray = Array.isArray(templates) ? templates : [];
                
                // Find template by ID or name
                const selectedTemplate = templatesArray.find((template: any) => 
                  template.id === templateId || 
                  template.id === parseInt(templateId) ||
                  template.name?.toLowerCase() === templateId.toLowerCase()
                );
    
                if (selectedTemplate && selectedTemplate.modifications) {
                  modifications = selectedTemplate.modifications;
                }
              }
    
              // Fallback to the old modifications endpoint if template doesn't have modifications
              if (modifications.length === 0) {
                const resolvedTemplateId = await resolveStudioTemplateId(templateId, actualApiKey);
                if (resolvedTemplateId) {
                  const response = await fetch(`${ORSHOT_API_BASE}/v1/studio/template/modifications?templateId=${resolvedTemplateId}`, {
                    method: "GET",
                    headers: {
                      "Authorization": `Bearer ${actualApiKey}`,
                      "Content-Type": "application/json",
                    },
                  });
    
                  if (response.ok) {
                    const modData = await response.json();
                    modifications = Array.isArray(modData) ? modData : [];
                  }
                }
              }
            } catch (error) {
              console.error("Error fetching studio template modifications:", error);
            }
          }
    
          if (modifications.length === 0) {
            return {
              content: [
                {
                  type: "text",
                  text: `No modifications found for ${detectedType} template "${templateId}". This template may not have any customizable elements.`,
                },
              ],
            };
          }
    
          const modificationsList = modifications.map((mod: any, index: number) => {
            const key = mod.key || mod.id;
            const description = mod.helpText || mod.description || 'No description';
            const example = mod.example ? ` (e.g., "${mod.example}")` : '';
            const type = mod.type ? ` [${mod.type}]` : '';
    
            return `${index + 1}. **${key}**${type}${example}
       ${description}`;
          }).join('\n\n');
    
          return {
            content: [
              {
                type: "text",
                text: `Found ${modifications.length} modification(s) for ${detectedType} template "${templateId}":\n\n${modificationsList}`,
              },
            ],
          };
    
        } catch (error) {
          return {
            content: [
              {
                type: "text",
                text: `Failed to fetch template modifications: ${error instanceof Error ? error.message : 'Unknown error'}`,
              },
            ],
          };
        }
      }
    );
  • Handler function for get-template-modifications tool. Validates inputs, auto-detects template type using getTemplateType helper, fetches template details or directly modifications from Orshot API endpoints based on type, formats the list of modifications (keys, descriptions, examples, types).
    async (args) => {
      const { apiKey, templateId, templateType } = args;
      const actualApiKey = apiKey || DEFAULT_API_KEY;
      
      if (!actualApiKey) {
        return {
          content: [
            {
              type: "text",
              text: "No API key provided. Please provide an API key parameter or set ORSHOT_API_KEY environment variable.",
            },
          ],
        };
      }
    
      try {
        let modifications: any[] = [];
        let detectedType: "library" | "studio" = templateType === "auto" ? "library" : templateType;
    
        if (templateType === "auto") {
          // Auto-detect template type
          const autoDetectedType = await getTemplateType(templateId, actualApiKey);
          if (!autoDetectedType) {
            return {
              content: [
                {
                  type: "text",
                  text: `Template "${templateId}" not found in either library or studio templates.`,
                },
              ],
            };
          }
          detectedType = autoDetectedType;
        }
    
        if (detectedType === "library") {
          // Get library template modifications
          try {
            // First try to get template details from the templates endpoint
            const templatesResponse = await fetch(`${ORSHOT_API_BASE}/v1/templates`, {
              method: "GET",
              headers: {
                "Authorization": `Bearer ${actualApiKey}`,
                "Content-Type": "application/json",
              },
            });
    
            if (templatesResponse.ok) {
              const templates = await templatesResponse.json();
              const templateArray = Array.isArray(templates) ? templates : [];
              const selectedTemplate = templateArray.find((template: any) => template.id === templateId);
    
              if (selectedTemplate && selectedTemplate.modifications) {
                modifications = selectedTemplate.modifications;
              }
            }
    
            // Fallback to modifications endpoint if template doesn't have modifications
            if (modifications.length === 0) {
              const modResponse = await fetch(`${ORSHOT_API_BASE}/v1/templates/modifications?template_id=${templateId}`, {
                method: "GET",
                headers: {
                  "Authorization": `Bearer ${actualApiKey}`,
                  "Content-Type": "application/json",
                },
              });
    
              if (modResponse.ok) {
                const modData = await modResponse.json();
                modifications = Array.isArray(modData) ? modData : [];
              }
            }
          } catch (error) {
            console.error("Error fetching library template modifications:", error);
          }
        } else if (detectedType === "studio") {
          // Get studio template modifications
          try {
            // First try to get template details from the templates endpoint
            const templatesResponse = await fetch(`${ORSHOT_API_BASE}/v1/studio/templates`, {
              method: "GET",
              headers: {
                "Authorization": `Bearer ${actualApiKey}`,
                "Content-Type": "application/json",
              },
            });
    
            if (templatesResponse.ok) {
              const templates = await templatesResponse.json();
              const templatesArray = Array.isArray(templates) ? templates : [];
              
              // Find template by ID or name
              const selectedTemplate = templatesArray.find((template: any) => 
                template.id === templateId || 
                template.id === parseInt(templateId) ||
                template.name?.toLowerCase() === templateId.toLowerCase()
              );
    
              if (selectedTemplate && selectedTemplate.modifications) {
                modifications = selectedTemplate.modifications;
              }
            }
    
            // Fallback to the old modifications endpoint if template doesn't have modifications
            if (modifications.length === 0) {
              const resolvedTemplateId = await resolveStudioTemplateId(templateId, actualApiKey);
              if (resolvedTemplateId) {
                const response = await fetch(`${ORSHOT_API_BASE}/v1/studio/template/modifications?templateId=${resolvedTemplateId}`, {
                  method: "GET",
                  headers: {
                    "Authorization": `Bearer ${actualApiKey}`,
                    "Content-Type": "application/json",
                  },
                });
    
                if (response.ok) {
                  const modData = await response.json();
                  modifications = Array.isArray(modData) ? modData : [];
                }
              }
            }
          } catch (error) {
            console.error("Error fetching studio template modifications:", error);
          }
        }
    
        if (modifications.length === 0) {
          return {
            content: [
              {
                type: "text",
                text: `No modifications found for ${detectedType} template "${templateId}". This template may not have any customizable elements.`,
              },
            ],
          };
        }
    
        const modificationsList = modifications.map((mod: any, index: number) => {
          const key = mod.key || mod.id;
          const description = mod.helpText || mod.description || 'No description';
          const example = mod.example ? ` (e.g., "${mod.example}")` : '';
          const type = mod.type ? ` [${mod.type}]` : '';
    
          return `${index + 1}. **${key}**${type}${example}
     ${description}`;
        }).join('\n\n');
    
        return {
          content: [
            {
              type: "text",
              text: `Found ${modifications.length} modification(s) for ${detectedType} template "${templateId}":\n\n${modificationsList}`,
            },
          ],
        };
    
      } catch (error) {
        return {
          content: [
            {
              type: "text",
              text: `Failed to fetch template modifications: ${error instanceof Error ? error.message : 'Unknown error'}`,
            },
          ],
        };
      }
    }
  • Input schema using Zod for validation of apiKey (optional), templateId (required string), templateType (enum: library/studio/auto, default auto).
    {
      apiKey: z.string().optional().describe("Orshot API key for authentication (optional if set in environment)"),
      templateId: z.string().describe("The ID or name of the template to get modifications for"),
      templateType: z.enum(["library", "studio", "auto"]).default("auto").describe("Type of template (library, studio, or auto-detect)"),
  • Helper function used by the tool handler for auto-detecting whether a templateId refers to a library or studio template by querying both APIs.
    // Helper function to determine template type (library vs studio)
    async function getTemplateType(templateId: string, apiKey: string): Promise<'library' | 'studio' | null> {
      try {
        // If it's a numeric ID, it's likely a studio template - check studio first
        if (isLikelyStudioTemplate(templateId)) {
          // Check studio templates first for numeric IDs
          const studioResponse = await fetch(`${ORSHOT_API_BASE}/v1/studio/templates`, {
            headers: {
              "Authorization": `Bearer ${apiKey}`,
              "Content-Type": "application/json",
            },
          });
    
          if (studioResponse.ok) {
            const studioTemplates = await studioResponse.json();
            const templatesArray = Array.isArray(studioTemplates) ? studioTemplates : [];
            
            // Check if templateId exists in studio templates (supports both numeric ID and name matching)
            const isStudioTemplate = templatesArray.some((template: any) => 
              template.id === templateId || 
              template.id === parseInt(templateId) ||
              template.name?.toLowerCase() === templateId.toLowerCase()
            );
            
            if (isStudioTemplate) {
              return 'studio';
            }
          }
        }
    
        // First check if it's a library template
        const libraryResponse = await fetch(`${ORSHOT_API_BASE}/v1/templates`, {
          headers: {
            "Authorization": `Bearer ${apiKey}`,
            "Content-Type": "application/json",
          },
        });
    
        if (libraryResponse.ok) {
          const libraryData = await libraryResponse.json();
          const libraryTemplates = Array.isArray(libraryData) ? libraryData : [];
          
          // Check if templateId exists in library templates
          const isLibraryTemplate = libraryTemplates.some((template: any) => 
            template.id === templateId || template.template_id === templateId
          );
          
          if (isLibraryTemplate) {
            return 'library';
          }
        }
    
        // If not found in library and not numeric, check studio templates (including name matching)
        if (!isLikelyStudioTemplate(templateId)) {
          const studioResponse = await fetch(`${ORSHOT_API_BASE}/v1/studio/templates`, {
            headers: {
              "Authorization": `Bearer ${apiKey}`,
              "Content-Type": "application/json",
            },
          });
    
          if (studioResponse.ok) {
            const studioTemplates = await studioResponse.json();
            const templatesArray = Array.isArray(studioTemplates) ? studioTemplates : [];
            
            // Check if templateId exists in studio templates (supports name matching for non-numeric IDs)
            const isStudioTemplate = templatesArray.some((template: any) => 
              template.id === templateId || 
              template.name?.toLowerCase() === templateId.toLowerCase()
            );
            
            if (isStudioTemplate) {
              return 'studio';
            }
          }
        }
    
        return null; // Template not found in either
      } catch (error) {
        console.error("Error determining template type:", error);
        return null;
      }
    }
  • Helper function used in studio template handling to resolve template name to ID.
    async function resolveStudioTemplateId(templateIdOrName: string, apiKey: string): Promise<string | null> {
      try {
        // If it's already a numeric ID, return as-is
        if (isLikelyStudioTemplate(templateIdOrName)) {
          return templateIdOrName;
        }
    
        // Fetch studio templates to find by name
        const studioResponse = await fetch(`${ORSHOT_API_BASE}/v1/studio/templates`, {
          headers: {
            "Authorization": `Bearer ${apiKey}`,
            "Content-Type": "application/json",
          },
        });
    
        if (studioResponse.ok) {
          const studioTemplates = await studioResponse.json();
          const templatesArray = Array.isArray(studioTemplates) ? studioTemplates : [];
          
          // Find template by name (case-insensitive) or exact ID match
          const matchedTemplate = templatesArray.find((template: any) => 
            template.name?.toLowerCase() === templateIdOrName.toLowerCase() ||
            template.id === templateIdOrName
          );
          
          if (matchedTemplate) {
            logger.debug(`Resolved template name "${templateIdOrName}" to ID: ${matchedTemplate.id}`);
            return String(matchedTemplate.id);
          }
        }
    
        return null; // Template not found
      } catch (error) {
        logger.error("Error resolving studio template ID", { templateIdOrName, error: error instanceof Error ? error.message : String(error) });
        return null;
      }
    }
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It mentions authentication via apiKey (optional if set in environment) and template handling, but doesn't describe the return format (e.g., list of modifications, JSON structure), error conditions, rate limits, or whether it's a read-only operation. This leaves significant gaps for a tool with no annotation coverage.

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 appropriately sized with two sentences, front-loaded with the core purpose and followed by a clarifying detail about template handling. There is no wasted language, and every sentence contributes useful information.

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

Completeness2/5

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

Given no annotations and no output schema, the description is incomplete for a tool with 3 parameters and behavioral complexity. It lacks details on what 'modifications' means in the return value, error handling, or operational constraints, making it inadequate for full agent understanding without additional context.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already documents all parameters (apiKey, templateId, templateType) with descriptions and enum values. The description adds minimal value beyond the schema by noting that templateId can be ID or name for studio templates, but doesn't provide additional syntax or format details. Baseline 3 is appropriate when the schema does the heavy lifting.

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

Purpose4/5

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

The description clearly states the action ('Get available modifications') and resource ('for a specific template'), distinguishing it from sibling tools like get-library-templates or get-studio-templates. However, it doesn't specify what 'modifications' entail (e.g., editing options, versions, customizations), leaving some ambiguity about the exact output.

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

Usage Guidelines3/5

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

The description implies usage by specifying it works for both library and studio templates and mentions ID or name for studio templates, providing some context. However, it lacks explicit guidance on when to use this tool versus alternatives like get-library-templates or get-studio-templates, and doesn't mention prerequisites or exclusions.

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/rishimohan/orshot-mcp-server'

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