mcp-google-apps-script
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| ASKADS_TELEMETRY | No | Set to 0 to opt out of anonymous telemetry. | 1 |
| GOOGLE_APPS_SCRIPT_API_BASE | No | Google Apps Script API base URL override. | |
| GOOGLE_APPS_SCRIPT_CLIENT_ID | No | OAuth client ID. | |
| GOOGLE_APPS_SCRIPT_TIMEOUT_MS | No | Per-request timeout; default 60000 ms. | 60000 |
| GOOGLE_APPS_SCRIPT_MAX_RETRIES | No | Temporary-error retries; default 3. | 3 |
| GOOGLE_APPS_SCRIPT_ACCESS_TOKEN | No | Short-lived alternative to the OAuth trio. | |
| GOOGLE_APPS_SCRIPT_CLIENT_SECRET | No | OAuth client secret. | |
| GOOGLE_APPS_SCRIPT_REFRESH_TOKEN | No | OAuth refresh token. |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": true
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| auth_statusA | Shows whether this server is connected to Google: token presence and source (env variables or a stored in-chat login), expiry, the Google account email, granted vs missing OAuth scopes, where the credentials file lives and where the OAuth client comes from. Makes no network calls and never returns the token itself. Call it first when other tools report the server is not connected. |
| set_clientA | Saves the OAuth client credentials from the JSON file downloaded from Google Cloud Console ('Download JSON' on a Desktop-app client). Pass the file PATH — the secret must never be pasted into the chat. The client is stored once in the shared ~/.config/mcp-google-auth/client.json (owner-only) and reused by every mcp-google-* server; tokens stay per-server. After this, call start_login. |
| start_loginA | First step of connecting from the chat, without editing config files or restarting the client. Returns authorizeUrl — show it to the user as a clickable link and ask them to open it in the browser ON THIS MACHINE, pick the Google account and approve access. A one-shot listener on 127.0.0.1 catches Google's redirect; the code is exchanged locally and never passes through the chat. Does not open the browser itself. The attempt lives 10 minutes; when the browser shows the success page, call finish_login. |
| finish_loginA | Second step: confirms the browser consent finished, saves the tokens to an owner-only file and verifies the login with a read-only identity call, returning the account email and the granted scopes. After success every tool works immediately — no client restart. If the user granted only part of the requested permissions, the login is still saved and missingScopes lists what will not work. Logging in under a different Google account replaces the previous login (its refresh token is revoked best-effort) and the response carries previousAccountEmail so the change never goes unnoticed. |
| logoutA | Revokes the stored token at Google (oauth2.googleapis.com/revoke) and deletes the local credentials file. Tokens supplied via env variables are NOT touched — remove them from the MCP client config manually; envTokenStillSet in the response says whether any are still in effect. |
| create_projectA | Creates an Apps Script project and returns it (scriptId, title, createTime). Without parent_id the project is standalone (its scriptId doubles as its Drive file id); with parent_id — the Drive id of a Google Doc, Sheet, Slides or Form — the project is created bound to that container and can use its container-specific APIs (e.g. SpreadsheetApp.getActive()). A new project holds only a default manifest and an empty Code file: add real code with update_project_content next. IMPORTANT: the API cannot list or delete projects — keep the returned scriptId, it is the only handle. Requires the script.projects scope, the Apps Script API toggle at script.google.com/home/usersettings, and — for bound projects — access to the parent file. |
| get_projectA | Returns the project's metadata: title, scriptId, parentId (present only for bound projects), creator, lastModifyUser, createTime and updateTime. No code is included — use get_project_content for the files. Useful to verify a scriptId exists and check whether the project is standalone or bound. |
| get_project_contentA | Returns the project's full file set: files[] with name (no extension), type (SERVER_JS = .gs code, HTML, JSON = the "appsscript" manifest), source, and per-file update info. By default HEAD (the latest saved code) is returned; version_number returns the content of that immutable version instead. Call this before update_project_content: replace mode needs the full new set including the manifest, and merge mode addresses files by these exact names. |
| update_project_contentA | Writes code files to the project's HEAD (deployed versions are untouched until you create a version + deployment). Two modes. mode="merge" (default, safer): the current content is read first, the given files are added or overwritten BY NAME, delete_files removes named files, everything else is preserved — not atomic, a concurrent edit between read and write is lost. mode="replace": the given files become the ENTIRE project; any file not in the list is deleted, and the list must include the "appsscript" manifest (type json) or the call is rejected before hitting the API. File names carry no extension ("Code", not "Code.gs"); the manifest cannot be deleted. Returns the resulting file set. This write is never retried after a 5xx or timeout — check with get_project_content before re-sending. |
| get_project_metricsA | Returns execution metrics for the project: activeUsers, totalExecutions and failedExecutions as time series ({ value, startTime, endTime }; value is absent when zero). granularity daily covers the last 7 days, weekly aggregates by week. deployment_id narrows the numbers to one deployment. A rising failedExecutions count is the cue to call list_processes with statuses=[FAILED] for the concrete failures. Requires the script.metrics scope. |
| create_versionA | Snapshots the project's current HEAD content as a new immutable version and returns it (versionNumber, description, createTime). Versions cannot be edited or deleted, and version numbers only grow — every call creates a NEW version, so do not re-send after an ambiguous failure without checking list_versions first. Creating a version does not change what runs anywhere: point a deployment at the new versionNumber via manage_deployments (action=create or update) to ship it. |
| list_versionsA | Lists the project's immutable versions (versionNumber, description, createTime), newest first. Paginate with page_token from nextPageToken. Use it to pick a versionNumber for manage_deployments or to read old code via get_project_content with version_number. |
| get_versionA | Fetches one immutable version by its number: versionNumber, description and createTime. For the code of that version call get_project_content with version_number instead — this endpoint returns metadata only. |
| manage_deploymentsA | Manages the project's deployments — the published entry points (web app, API executable, add-on) that make code callable from outside the editor. action=create deploys version_number (omit it to deploy HEAD — updates live with every save; fine for testing, risky for production) with an optional description. action=list shows all deployments including the automatic @HEAD one (paginate with page_token from nextPageToken); get needs deployment_id and returns entryPoints[] — the web app URL (webApp.url) and the API-executable config run_function depends on. action=update repoints an existing deployment at another version_number and/or changes its description (this is how you ship or roll back without changing the URL; the current config is read first and merged, so omitted fields are preserved); delete removes it permanently and breaks its URL/integrations (the @HEAD deployment cannot be deleted). WHAT a deployment exposes (web app vs API executable, who can access) comes from the appsscript manifest at the deployed version — set it via update_project_content before creating the version. Requires the script.deployments scope. |
| run_functionA | Runs a named function in the script and returns { done, result } — or, when the script itself throws, { done, script_error: { type, message, stack } } with the Apps Script stack trace (this is a script bug, not a transport error; do not blindly retry, the function may have side effects). HARD PREREQUISITES the API enforces: (1) the script must have an API-executable deployment (Deploy > New deployment > API executable, or a manifest with executionApi); (2) this server's OAuth client must belong to the SAME Google Cloud project as the script (script editor > Project Settings > change the GCP project number); (3) the OAuth token must carry every scope the script itself uses (listed in the editor under Project Settings > Show "appsscript.json") — otherwise the call fails with 403 PERMISSION_DENIED or 404. parameters are positional and must be JSON-serializable (no Apps Script objects like Document or Range). dev_mode=true runs the latest saved code instead of the deployed version — owner only. Executions time out after 6 minutes on the Apps Script side. |
| list_processesA | Lists execution processes (the execution history): each entry carries projectName, functionName, processType (WEBAPP, EXECUTION_API, TIME_DRIVEN, TRIGGER, SIMPLE_TRIGGER, ADD_ON, EDITOR, MENU, BATCH_TASK), processStatus (COMPLETED, FAILED, TIMED_OUT, RUNNING, PAUSED, CANCELED, DELAYED, UNKNOWN), userAccessLevel, startTime and duration. With script_id only that script's executions are listed; without it, ALL executions started by the authorizing user across their scripts. To hunt errors, filter statuses=["FAILED","TIMED_OUT"] — but note the API returns no error messages or logs here, only the fact and time of failure: get the message by re-running via run_function, or from the Apps Script dashboard / Cloud Logging. start_time/end_time (RFC3339 UTC) bound the process start; paginate with page_token. Requires the script.processes scope. |
| setup_instructionsA | Returns the setup checklist for this server as structured JSON: how to enable the Apps Script API (the per-account toggle at script.google.com/home/usersettings AND the Cloud-project API), which OAuth scope each tool needs (so the operator can mint a minimal-scope refresh token), the extra prerequisites of run_function (API-executable deployment, same-Cloud-project OAuth client, the script's own scopes), and the API's known limits. Works without credentials — call it first when any tool fails with 403 PERMISSION_DENIED or when setting the server up. |
| raw_requestA | Escape hatch to call any Google Apps Script API v1 path directly, for requests the typed tools don't cover — e.g. GET "v1/projects//content?versionNumber=3", or a PUT to "v1/projects//content" with a hand-built files body. The path may carry a query string; repeated filter params can be encoded there (e.g. "v1/processes?userProcessFilter.statuses=FAILED&userProcessFilter.statuses=TIMED_OUT"). The Bearer token is added automatically and paths resolving to a foreign origin are rejected; the method defaults to GET. Remember: PUT v1/projects//content replaces the ENTIRE file set — prefer update_project_content, whose merge mode protects the other files. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 18 tools
The tools have mostly distinct purposes: auth lifecycle, project metadata, content, versions, deployments, executions, and raw API access are clearly separated. The only mild overlaps are between get_project/get_project_content/get_project_metrics and between typed tools and raw_request, but the descriptions make the intended boundaries clear.
Names are almost entirely consistent snake_case with a verb_noun pattern such as get_project, create_version, update_project_content, and list_processes. A few tools (auth_status, setup_instructions, logout) deviate slightly by using noun phrases or bare verbs, but the overall style remains predictable and readable.
Eighteen tools is slightly heavy but justified for covering the Apps Script API's auth, project, content, version, deployment, execution, and metrics surfaces. The auth/setup group adds several tools, and raw_request provides an explicit escape hatch, making the set a bit broad without feeling excessive.
The set covers the main Apps Script lifecycle: project metadata and creation, content reading and updating, immutable versions, deployment management via manage_deployments, function execution, execution history, metrics, and OAuth setup. Missing operations such as project deletion or version editing are either not supported by the underlying API or explicitly handled by raw_request.