Skip to main content
Glama
mohalmah

Google Apps Script MCP Server

by mohalmah

script_run

Execute Google Apps Script code by providing the script ID to automate tasks in Google Workspace applications.

Instructions

Run a Google Apps Script.

Input Schema

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

Implementation Reference

  • Handler function that executes the 'script_run' tool by making an authenticated POST request to the Google Apps Script API endpoint `/v1/scripts/{scriptId}:run`.
    const executeFunction = async ({ scriptId, fields, alt = 'json', key, access_token, oauth_token, quotaUser, prettyPrint = true }) => {
      const baseUrl = 'https://script.googleapis.com';
      const url = new URL(`${baseUrl}/v1/scripts/${scriptId}:run`);
      
      // Append query parameters to the URL
      const params = new URLSearchParams({
        fields,
        alt,
        key,
        access_token,
        oauth_token,
        quotaUser,
        prettyPrint: prettyPrint.toString(),
        '$.xgafv': '1',
        upload_protocol: 'raw',
        uploadType: 'raw'
      });
      
      url.search = params.toString();
    
      try {
        // Get OAuth headers
        const headers = await getAuthHeaders();
        headers['Content-Type'] = 'application/json';
        // Perform the fetch request
        const response = await fetch(url.toString(), {
          method: 'POST',
          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,
          timestamp: new Date().toISOString(),
          errorType: error.name || 'Unknown'
        };
    
        logger.error('SCRIPT_RUN', 'Error running the script', errorDetails);
        
        console.error('❌ Error running the script:', errorDetails);
        
        // Return detailed error information for debugging
        return { 
          error: true,
          message: error.message,
          details: errorDetails,
          rawError: {
            name: error.name,
            stack: error.stack
          }
        };
      }
    };
  • Schema definition for the 'script_run' tool, specifying input parameters and required fields.
      type: 'function',
      function: {
        name: 'script_run',
        description: 'Run a Google Apps Script.',
        parameters: {
          type: 'object',
          properties: {
            scriptId: {
              type: 'string',
              description: 'The ID of the script to run.'
            },
            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.'
            },
            oauth_token: {
              type: 'string',
              description: 'OAuth 2.0 token for the current user.'
            },
            quotaUser: {
              type: 'string',
              description: 'Available to use for quota purposes for server-side applications.'
            },
            prettyPrint: {
              type: 'boolean',
              description: 'Returns response with indentations and line breaks.'
            }
          },
          required: ['scriptId']
        }
      }
    }
  • lib/tools.js:8-64 (registration)
    Central tool registration via dynamic discovery of all `apiTool` exports from paths listed in tools/paths.js, including the 'script_run' tool.
    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;
    }
  • tools/paths.js:1-18 (registration)
    Explicit listing of tool paths for discovery, including 'google-app-script-api/apps-script-api/script-scripts-run.js' at line 10.
    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'
    ];

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