Skip to main content
Glama
mohalmah

Google Apps Script MCP Server

by mohalmah

script_projects_versions_get

Retrieve a specific version of a Google Apps Script project by providing the script ID and version number to access historical code states.

Instructions

Get a version of a Google Apps Script project.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
scriptIdYesThe ID of the script project.
versionNumberYesThe version number of the script project.
fieldsNoSelector specifying which fields to include in a partial response.
altNoData format for response.
keyNoAPI key for the project.
access_tokenNoOAuth access token.
quotaUserNoAvailable to use for quota purposes for server-side applications.
oauth_tokenNoOAuth 2.0 token for the current user.
callbackNoJSONP callback.
prettyPrintNoReturns response with indentations and line breaks.

Implementation Reference

  • Main handler function that performs the HTTP GET request to retrieve a specific version of a Google Apps Script project.
    const executeFunction = async ({ scriptId, versionNumber, fields, alt = 'json', key, access_token, quotaUser, oauth_token, callback, prettyPrint = true }) => {
      const baseUrl = 'https://script.googleapis.com';
      const token = process.env.GOOGLE_APP_SCRIPT_API_API_KEY;
      const url = new URL(`${baseUrl}/v1/projects/${scriptId}/versions/${versionNumber}`);
    
      // Append query parameters
      const params = new URLSearchParams({
        fields,
        alt,
        key,
        access_token,
        quotaUser,
        oauth_token,
        callback,
        prettyPrint: prettyPrint.toString(),
        '$.xgafv': '1',
        upload_protocol: 'raw',
        uploadType: 'media'
      });
    
      // Set up headers for the request
      const headers = {
        'Accept': 'application/json'
      };
    
      // If a token is provided, add it to the Authorization header
      if (token) {
        headers['Authorization'] = `Bearer ${token}`;
      }
    
      // Perform the fetch request
      try {
        const response = await fetch(`${url}?${params.toString()}`, {
          method: 'GET',
          headers
        });
    
        // Check if the response was successful
        if (!response.ok) {
          const errorData = await response.json();
          throw new Error(errorData);
        }
    
        // Parse and return the response data
        const data = await response.json();
        return data;
      } catch (error) {
        const errorDetails = {
          message: error.message,
          stack: error.stack,
          scriptId,
          versionNumber,
          timestamp: new Date().toISOString(),
          errorType: error.name || 'Unknown'
        };
    
        logger.error('VERSION_GET', 'Error retrieving script version', errorDetails);
        
        console.error('❌ Error retrieving script version:', errorDetails);
        
        // Return detailed error information for debugging
        return { 
          error: true,
          message: error.message,
          details: errorDetails,
          rawError: {
            name: error.name,
            stack: error.stack
          }
        };
      }
    };
  • Tool definition object containing the schema for inputs (parameters with types, descriptions, required fields) and references the handler function.
    const apiTool = {
      function: executeFunction,
      definition: {
        type: 'function',
        function: {
          name: 'script_projects_versions_get',
          description: 'Get a version of a Google Apps Script project.',
          parameters: {
            type: 'object',
            properties: {
              scriptId: {
                type: 'string',
                description: 'The ID of the script project.'
              },
              versionNumber: {
                type: 'string',
                description: 'The version number of the script project.'
              },
              fields: {
                type: 'string',
                description: 'Selector specifying which fields to include in a partial response.'
              },
              alt: {
                type: 'string',
                enum: ['json', 'xml'],
                description: 'Data format for response.'
              },
              key: {
                type: 'string',
                description: 'API key for the project.'
              },
              access_token: {
                type: 'string',
                description: 'OAuth access token.'
              },
              quotaUser: {
                type: 'string',
                description: 'Available to use for quota purposes for server-side applications.'
              },
              oauth_token: {
                type: 'string',
                description: 'OAuth 2.0 token for the current user.'
              },
              callback: {
                type: 'string',
                description: 'JSONP callback.'
              },
              prettyPrint: {
                type: 'boolean',
                description: 'Returns response with indentations and line breaks.'
              }
            },
            required: ['scriptId', 'versionNumber']
          }
        }
      }
    };
  • tools/paths.js:1-18 (registration)
    Lists the relative path to the tool implementation file within the array used for dynamic tool discovery.
    export const toolPaths = [
      'google-app-script-api/apps-script-api/script-projects-deployments-delete.js',
      'google-app-script-api/apps-script-api/script-projects-create.js',
      'google-app-script-api/apps-script-api/script-projects-versions-create.js',
      'google-app-script-api/apps-script-api/script-projects-deployments-create.js',
      'google-app-script-api/apps-script-api/script-projects-deployments-update.js',
      'google-app-script-api/apps-script-api/script-projects-deployments-list.js',
      'google-app-script-api/apps-script-api/script-projects-update-content.js',
      'google-app-script-api/apps-script-api/script-projects-deployments-get.js',
      'google-app-script-api/apps-script-api/script-scripts-run.js',
      'google-app-script-api/apps-script-api/script-projects-get.js',
      'google-app-script-api/apps-script-api/script-processes-list-script-processes.js',
      'google-app-script-api/apps-script-api/script-projects-get-metrics.js',
      'google-app-script-api/apps-script-api/script-projects-get-content.js',
      'google-app-script-api/apps-script-api/script-projects-versions-list.js',
      'google-app-script-api/apps-script-api/script-projects-versions-get.js',
      'google-app-script-api/apps-script-api/script-processes-list.js'
    ];
  • lib/tools.js:8-64 (registration)
    Dynamically discovers and loads MCP tools by importing modules from toolPaths, validating apiTool export, wrapping handlers with logging, and returning the list of tools for registration.
    export async function discoverTools() {
      logger.info('DISCOVERY', `Starting tool discovery for ${toolPaths.length} tool paths`);
      
      const toolPromises = toolPaths.map(async (file) => {
        try {
          logger.debug('DISCOVERY', `Loading tool from: ${file}`);
          const module = await import(`../tools/${file}`);
          
          if (!module.apiTool) {
            logger.warn('DISCOVERY', `Tool file missing apiTool export: ${file}`);
            return null;
          }
    
          const toolName = module.apiTool.definition?.function?.name;
          if (!toolName) {
            logger.warn('DISCOVERY', `Tool missing function name: ${file}`);
            return null;
          }
    
          // Wrap the original function with logging
          const originalFunction = module.apiTool.function;
          const wrappedFunction = withLogging(toolName, originalFunction);
    
          logger.debug('DISCOVERY', `Successfully loaded tool: ${toolName}`, {
            file,
            toolName,
            description: module.apiTool.definition?.function?.description
          });
    
          return {
            ...module.apiTool,
            function: wrappedFunction,
            path: file,
          };
        } catch (error) {
          logger.error('DISCOVERY', `Failed to load tool: ${file}`, {
            file,
            error: {
              message: error.message,
              stack: error.stack
            }
          });
          return null;
        }
      });
      
      const tools = (await Promise.all(toolPromises)).filter(Boolean);
      
      logger.info('DISCOVERY', `Tool discovery completed`, {
        totalPaths: toolPaths.length,
        successfullyLoaded: tools.length,
        failed: toolPaths.length - tools.length,
        toolNames: tools.map(t => t.definition?.function?.name).filter(Boolean)
      });
      
      return 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/mohalmah/google-appscript-mcp-server'

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