Agent skill

Google Apps Script

by jezweb in jezweb/claude-skills

Build Google Apps Script automation for Sheets and Workspace.

MITAuto-check passedDocuments & Office

Install Google Apps Script

skills CLI
$ npx skills add jezweb/claude-skills --skill google-apps-script -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install jezweb/claude-skills google-apps-script --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/jezweb/claude-skills.git skills-src && mkdir -p .claude/skills && cp -r skills-src/plugins/integrations/skills/google-apps-script .claude/skills/google-apps-script && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
google-apps-script
GitHub stars
1.1k
Token cost
~4.7k tokens
SKILL.md length
1,038 words
Files
1
Skills in repo
52
Repo updated
First seen
Licence
MIT

At a glance

Build Google Apps Script automation for Sheets and Workspace.

  • Works in 4 steps: Understand the Automation → Generate the Script → Provide Installation Instructions → …
  • (onEdit / time-driven / form submit)
  • SKILL.md covers What You Produce, Workflow, Script Structure Template and Critical Rules, plus 4 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Google Apps Script is an agent skill from jezweb/claude-skills. Build Google Apps Script automation for Sheets and Workspace. Custom menus, triggers (onEdit / time-driven / form submit), dialogs, sidebars, email batches, PDF export, external API. Use whenever the user wants to automate a Google Sheet, build a Sheets menu / sidebar / dialog, hit a Sheets row from email or a webhook, schedule a Sheets workflow, or asks 'how do I script this in Sheets'.

Its SKILL.md is about 4.7k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts. Compatibility notes: claude-code-only

It sits in Documents & Office, covering Excel spreadsheets, Webhooks and PDF. It works with Google Sheets. The repository describes itself as: Skills for Claude Code CLI such as full stack dev Cloudflare, React, Tailwind v4, and AI integrations. The licence is MIT.

When your agent uses it

  • (onEdit / time-driven / form submit)
  • The user wants to automate a Google Sheet
  • Build a Sheets menu / sidebar / dialog
  • Hit a Sheets row from email

Example prompts

  • “how do I script this in Sheets”
  • “/google-apps-script”

Requirements

  • Compatibility (from SKILL.md): claude-code-only

Workflow steps

4 steps, taken from the step headings in SKILL.md.

  1. Understand the Automation
  2. Generate the Script
  3. Provide Installation Instructions
  4. First-Time Authorisation

What it can do on your machine

Read from SKILL.md and the folder at commit 64965d9. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are javascript).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

  • Compatibility

    claude-code-only

    From compatibility in the SKILL.md frontmatter.

Context cost

Google Apps Script loads about 4.7k tokens when it runs. Until then it costs about 102 tokens; SKILL.md has 1,038 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~102
When it runs · the whole SKILL.md, loaded when a task matches
~4.7k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from jezweb/claude-skills at commit 64965d9, republished under its MIT licence (© jezweb). 1,038 words, ~4,714 tokens.

Download SKILL.mdSave it as .claude/skills/google-apps-script/SKILL.md (or your agent's skills folder).
name
google-apps-script
description
Build Google Apps Script automation for Sheets and Workspace. Custom menus, triggers (onEdit / time-driven / form submit), dialogs, sidebars, email batches, PDF export, external API. Use whenever the user wants to automate a Google Sheet, build a Sheets menu / sidebar / dialog, hit a Sheets row from email or a webhook, schedule a Sheets workflow, or asks 'how do I script this in Sheets'.
compatibility
claude-code-only

Google Apps Script

Build automation scripts for Google Sheets and Workspace apps. Scripts run server-side on Google's infrastructure with a generous free tier.

What You Produce

  • Apps Script code pasted into Extensions > Apps Script
  • Custom menus, dialogs, sidebars
  • Automated triggers (on edit, time-driven, form submit)
  • Email notifications, PDF exports, API integrations

Workflow

Step 1: Understand the Automation

Ask what the user wants automated. Common scenarios:

  • Custom menu with actions (report generation, data processing)
  • Auto-triggered behaviour (on edit, on form submit, scheduled)
  • Sidebar app for data entry
  • Email notifications from sheet data
  • PDF export and distribution
Step 2: Generate the Script

Follow the structure template below. Every script needs a header comment, configuration constants at top, and onOpen() for menu setup.

Step 3: Provide Installation Instructions

All scripts install the same way:

  1. Open the Google Sheet
  2. Extensions > Apps Script
  3. Delete any existing code in the editor
  4. Paste the script
  5. Click Save
  6. Close the Apps Script tab
  7. Reload the spreadsheet (onOpen runs on page load)
Step 4: First-Time Authorisation

Each user gets a Google OAuth consent screen on first run. For unverified scripts (most internal scripts), users must click:

Advanced > Go to [Project Name] (unsafe) > Allow

This is a one-time step per user. Warn users about this in your output.


Script Structure Template

Every script should follow this pattern:

javascript
/**
 * [Project Name] - [Brief Description]
 *
 * [What it does, key features]
 *
 * INSTALL: Extensions > Apps Script > paste this > Save > Reload sheet
 */

// --- CONFIGURATION ---
const SOME_SETTING = 'value';

// --- MENU SETUP ---
function onOpen() {
  const ui = SpreadsheetApp.getUi();
  ui.createMenu('My Menu')
    .addItem('Do Something', 'myFunction')
    .addSeparator()
    .addSubMenu(ui.createMenu('More Options')
      .addItem('Option A', 'optionA'))
    .addToUi();
}

// --- FUNCTIONS ---
function myFunction() {
  // Implementation
}

Critical Rules

Public vs Private Functions

Functions ending with _ (underscore) are private and CANNOT be called from client-side HTML via google.script.run. This is a silent failure -- the call simply doesn't work with no error.

javascript
// WRONG - dialog can't call this, fails silently
function doWork_() { return 'done'; }

// RIGHT - dialog can call this
function doWork() { return 'done'; }

Also applies to: Menu item function references must be public function names as strings.

Batch Operations (Critical for Performance)

Read/write data in bulk, never cell-by-cell. The difference is 70x.

javascript
// SLOW (70 seconds on 100x100) - reads one cell at a time
for (let i = 1; i <= 100; i++) {
  const val = sheet.getRange(i, 1).getValue();
}

// FAST (1 second) - reads all at once
const allData = sheet.getRange(1, 1, 100, 1).getValues();
for (const row of allData) {
  const val = row[0];
}

Always use getRange().getValues() / setValues() for bulk reads/writes.

V8 Runtime

V8 is the only runtime (Rhino was removed January 2026). Supports modern JavaScript: const, let, arrow functions, template literals, destructuring, classes, async/generators.

NOT available (use Apps Script alternatives):

Missing APIApps Script Alternative
setTimeout / setIntervalUtilities.sleep(ms) (blocking)
fetchUrlFetchApp.fetch()
FormDataBuild payload manually
URLString manipulation
cryptoUtilities.computeDigest() / Utilities.getUuid()
Flush Before Returning

Call SpreadsheetApp.flush() before returning from functions that modify the sheet, especially when called from HTML dialogs. Without it, changes may not be visible when the dialog shows "Done."

Simple vs Installable Triggers
FeatureSimple (onEdit)Installable
Auth requiredNoYes
Send emailNoYes
Access other filesNoYes
URL fetchNoYes
Open dialogsNoYes
Runs asActive userTrigger creator

Use simple triggers for lightweight reactions. Use installable triggers (via ScriptApp.newTrigger()) when you need email, external APIs, or cross-file access.

Custom Spreadsheet Functions

Functions used as =MY_FUNCTION() in cells have strict limitations:

javascript
/**
 * Calculates something custom.
 * @param {string} input The input value
 * @return {string} The result
 * @customfunction
 */
function MY_FUNCTION(input) {
  // Can use: basic JS, Utilities, CacheService
  // CANNOT use: MailApp, UrlFetchApp, SpreadsheetApp.getUi(), triggers
  return input.toUpperCase();
}
  • Must include @customfunction JSDoc tag
  • 30-second execution limit (vs 6 minutes for regular functions)
  • Cannot access services requiring authorisation

Quotas and Limits

ResourceFree AccountGoogle Workspace
Script runtime6 min / execution6 min / execution
Time-driven trigger runtime30 min30 min
Triggers total daily runtime90 min6 hours
Triggers total20 per user per script20 per user per script
Email recipients/day1001,500
URL Fetch calls/day20,000100,000
Properties storage500 KB500 KB
Custom function runtime30 seconds30 seconds
Simultaneous executions3030

Modal Progress Dialog

Block user interaction during long operations with a spinner that auto-closes. Use for any operation taking more than a few seconds.

Pattern: menu function > showProgress() > dialog calls action function > auto-close

javascript
function showProgress(message, serverFn) {
  const html = HtmlService.createHtmlOutput(`
    <style>
      body { font-family: 'Google Sans', Arial, sans-serif; display: flex;
        flex-direction: column; align-items: center; justify-content: center;
        height: 100%; margin: 0; padding: 20px; box-sizing: border-box; }
      .spinner { width: 36px; height: 36px; border: 4px solid #e0e0e0;
        border-top: 4px solid #1a73e8; border-radius: 50%;
        animation: spin 0.8s linear infinite; margin-bottom: 16px; }
      @keyframes spin { to { transform: rotate(360deg); } }
      .message { font-size: 14px; color: #333; text-align: center; }
      .done { color: #1e8e3e; font-weight: 500; }
      .error { color: #d93025; font-weight: 500; }
    </style>
    <div class="spinner" id="spinner"></div>
    <div class="message" id="msg">${message}</div>
    <script>
      google.script.run
        .withSuccessHandler(function(r) {
          document.getElementById('spinner').style.display = 'none';
          var m = document.getElementById('msg');
          m.className = 'message done';
          m.innerText = 'Done! ' + (r || '');
          setTimeout(function() { google.script.host.close(); }, 1200);
        })
        .withFailureHandler(function(err) {
          document.getElementById('spinner').style.display = 'none';
          var m = document.getElementById('msg');
          m.className = 'message error';
          m.innerText = 'Error: ' + err.message;
          setTimeout(function() { google.script.host.close(); }, 3000);
        })
        .${serverFn}();
    </script>
  `).setWidth(320).setHeight(140);
  SpreadsheetApp.getUi().showModalDialog(html, 'Working...');
}

// Menu calls this wrapper
function menuDoWork() {
  showProgress('Processing data...', 'doTheWork');
}

// MUST be public (no underscore) for the dialog to call it
function doTheWork() {
  // ... do the work ...
  SpreadsheetApp.flush();
  return 'Processed 50 rows';  // shown in success message
}

Common Patterns

Toast Notifications
javascript
SpreadsheetApp.getActiveSpreadsheet().toast('Operation complete!', 'Title', 5);
// Arguments: message, title, duration in seconds (-1 = until dismissed)
Alert and Prompt Dialogs
javascript
const ui = SpreadsheetApp.getUi();

// Yes/No confirmation
const response = ui.alert('Delete this data?', 'This cannot be undone.',
  ui.ButtonSet.YES_NO);
if (response === ui.Button.YES) { /* proceed */ }

// Prompt for input
const result = ui.prompt('Enter your name:', ui.ButtonSet.OK_CANCEL);
if (result.getSelectedButton() === ui.Button.OK) {
  const name = result.getResponseText();
}
Sidebar Apps

HTML panel on the right. Use google.script.run to call server functions.

javascript
function showSidebar() {
  const html = HtmlService.createHtmlOutput(`
    <h3>Quick Entry</h3>
    <select id="worker"><option>Craig</option><option>Steve</option></select>
    <input id="suburb" placeholder="Suburb">
    <button onclick="submit()">Add Job</button>
    <script>
      function submit() {
        google.script.run.withSuccessHandler(function() { alert('Added!'); })
          .addJob(document.getElementById('worker').value,
                  document.getElementById('suburb').value);
      }
    </script>
  `).setTitle('Job Entry').setWidth(300);
  SpreadsheetApp.getUi().showSidebar(html);
}

function addJob(worker, suburb) { // MUST be public (no underscore)
  SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().appendRow([new Date(), worker, suburb]);
}
Triggers

onEdit (simple trigger) -- limited permissions but no auth needed:

javascript
function onEdit(e) {
  const sheet = e.source.getActiveSheet();
  if (sheet.getName() !== 'Data') return;
  if (e.range.getColumn() !== 3) return;
  // Auto-timestamp when column C is edited
  sheet.getRange(e.range.getRow(), 4).setValue(new Date());
}

Installable triggers -- create via script, run setup function once manually:

javascript
function createTriggers() {
  // Time-driven: run every day at 8am
  ScriptApp.newTrigger('dailyReport')
    .timeBased().atHour(8).everyDays(1).create();

  // On edit with full permissions (can send email, fetch URLs)
  ScriptApp.newTrigger('onEditFull')
    .forSpreadsheet(SpreadsheetApp.getActive()).onEdit().create();

  // On form submit
  ScriptApp.newTrigger('onFormSubmit')
    .forSpreadsheet(SpreadsheetApp.getActive()).onFormSubmit().create();
}
Email from Sheets
javascript
function emailWeeklySchedule() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const data = sheet.getRange('A2:E10').getDisplayValues();
  let body = '<h2>Weekly Schedule</h2><table border="1" cellpadding="8">';
  body += '<tr><th>Job</th><th>Suburb</th><th>Time</th><th>Price</th></tr>';
  for (const row of data) {
    if (row[0]) body += '<tr>' + row.map(c => '<td>' + c + '</td>').join('') + '</tr>';
  }
  body += '</table>';
  MailApp.sendEmail({ to: 'worker@example.com',
    subject: 'Schedule - Week ' + sheet.getName(), htmlBody: body });
}
PDF Export

Non-obvious URL construction -- export parameters are undocumented:

javascript
function exportSheetAsPdf() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const url = ss.getUrl().replace(/\/edit.*$/, '')
    + '/export?exportFormat=pdf&format=pdf&size=A4&portrait=true'
    + '&fitw=true&sheetnames=false&printtitle=false&gridlines=false'
    + '&gid=' + ss.getActiveSheet().getSheetId();
  const blob = UrlFetchApp.fetch(url, {
    headers: { 'Authorization': 'Bearer ' + ScriptApp.getOAuthToken() }
  }).getBlob().setName('report.pdf');
  MailApp.sendEmail({ to: 'boss@example.com', subject: 'Weekly Report PDF',
    body: 'Attached.', attachments: [blob] });
}
External API Calls
javascript
// GET
function fetchData() {
  const r = UrlFetchApp.fetch('https://api.example.com/data', {
    headers: { 'Authorization': 'Bearer ' + getApiKey() } });
  return JSON.parse(r.getContentText());
}

// POST (muteHttpExceptions to handle errors yourself)
function postData(payload) {
  const r = UrlFetchApp.fetch('https://api.example.com/submit', {
    method: 'post', contentType: 'application/json',
    payload: JSON.stringify(payload), muteHttpExceptions: true });
  if (r.getResponseCode() !== 200) throw new Error('API error: ' + r.getContentText());
  return JSON.parse(r.getContentText());
}
Data Validation Dropdowns
javascript
// Dropdown from list
const rule = SpreadsheetApp.newDataValidation()
  .requireValueInList(['Option A', 'Option B', 'Option C'], true)
  .setAllowInvalid(false).setHelpText('Select an option').build();
sheet.getRange('C3:C50').setDataValidation(rule);

// Dropdown from range (e.g. a Lookups sheet)
const rule2 = SpreadsheetApp.newDataValidation()
  .requireValueInRange(ss.getSheetByName('Lookups').getRange('A1:A100')).build();
sheet.getRange('B3:B50').setDataValidation(rule2);
Show full SKILL.md (415 more words)Show less
Properties Service (Persistent Storage)

Three scopes: PropertiesService.getScriptProperties() (shared), .getUserProperties() (per user), .getDocumentProperties() (per spreadsheet). All use .setProperty(key, value) / .getProperty(key). 500 KB limit.


Recipes

Auto-Archive Completed Rows

Move rows with "Complete" status to an Archive sheet. Processes bottom-up to avoid shifting row indices.

javascript
function archiveCompleted() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const source = ss.getSheetByName('Active');
  const archive = ss.getSheetByName('Archive');
  const data = source.getDataRange().getValues();
  const statusCol = 4; // column E (0-indexed)

  for (let i = data.length - 1; i >= 1; i--) {
    if (data[i][statusCol] === 'Complete') {
      archive.appendRow(data[i]);
      source.deleteRow(i + 1); // +1 for 1-indexed rows
    }
  }
  SpreadsheetApp.flush();
}
Duplicate Detection and Highlighting

Pattern: read column with getValues(), track seen values in an object, highlight both the original and duplicate rows with setBackground('#f4cccc'). Process all data in one getValues() call, then set backgrounds individually (unavoidable for scattered highlights).

Batch Email Sender

Key pattern: check MailApp.getRemainingDailyQuota() before sending, mark status per row, wrap each send in try/catch.

javascript
function sendBatchEmails() {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Recipients');
  const data = sheet.getRange('A2:C' + sheet.getLastRow()).getValues(); // Email, Name, Status
  const remaining = MailApp.getRemainingDailyQuota();
  if (remaining < data.length) {
    SpreadsheetApp.getUi().alert('Only ' + remaining + ' emails left. Need ' + data.length);
    return;
  }
  let sent = 0;
  for (let i = 0; i < data.length; i++) {
    const [email, name, status] = data[i];
    if (!email || status === 'Sent') continue;
    try {
      MailApp.sendEmail({ to: email, subject: 'Your Weekly Update',
        htmlBody: '<p>Hi ' + name + ',</p><p>Here is your update...</p>' });
      sheet.getRange(i + 2, 3).setValue('Sent'); sent++;
    } catch (e) { sheet.getRange(i + 2, 3).setValue('Error: ' + e.message); }
  }
  SpreadsheetApp.flush();
}
Summary Dashboard Generator

Pattern: loop numbered weekly tabs (01-52), read summary cells from each, write aggregated rows into a Summary sheet. Use ss.getSheetByName(tabName) to iterate, ss.insertSheet('Summary') if it doesn't exist, summary.autoResizeColumns() at end, flush() before return.


Error Handling

Always wrap external calls in try/catch. Use muteHttpExceptions: true to handle HTTP errors yourself. Re-throw for dialog error handlers.

javascript
function fetchExternalData() {
  try {
    const response = UrlFetchApp.fetch('https://api.example.com/data', {
      headers: { 'Authorization': 'Bearer ' + getApiKey() },
      muteHttpExceptions: true
    });
    if (response.getResponseCode() !== 200)
      throw new Error('API returned ' + response.getResponseCode());
    return JSON.parse(response.getContentText());
  } catch (e) { Logger.log('Error: ' + e.message); throw e; }
}

Error Prevention

MistakeFix
Dialog can't call functionRemove trailing _ from function name
Script is slow on large dataUse getValues()/setValues() batch operations
Changes not visible after dialogAdd SpreadsheetApp.flush() before return
onEdit can't send emailUse installable trigger via ScriptApp.newTrigger()
Custom function times out30s limit -- simplify or move to regular function
setTimeout not foundUse Utilities.sleep(ms) (blocking)
Script exceeds 6 minBreak into chunks, use time-driven trigger for batches
Auth popup doesn't appearUser must click Advanced > Go to (unsafe) > Allow

Debugging

  • Logger.log() / console.log() -- View > Execution Log in Apps Script editor
  • Run manually -- select function in editor dropdown > Run
  • Executions tab -- shows all recent runs with errors and stack traces
  • Trigger failures -- script.google.com > My Projects > Executions
  • Always test on a copy of the sheet before deploying

Deployment Checklist

  • All functions called from HTML dialogs are public (no trailing underscore)
  • SpreadsheetApp.flush() called before returning from modifying functions
  • Error handling (try/catch) around external API calls and MailApp
  • Configuration constants at the top of the file
  • Header comment with install instructions
  • Tested on a copy of the sheet
  • Considered multi-user behaviour (different permissions, different active sheet)
  • Long operations use modal progress dialogs
  • No hardcoded sheet names -- use configuration constants
  • Checked email quota before batch sends

Reconstruct from Apps Script docs if needed

  • Row/Column show/hide — sheet.hideRows(), showRows(), isRowHiddenByUser()
  • Formatting — setBackground(), setFontWeight(), setBorder(), setNumberFormat(), conditional formatting
  • Data protection — range.protect(), setUnprotectedRanges(), editor management
  • Multiple sheets — getSheetByName(), looping numbered tabs, copyTo(), insertSheet()
  • Auto-numbering rows — onEdit trigger to auto-number column A when column B is edited
  • Google Chat webhooks — POST to chat.googleapis.com with JSON payload

© jezweb, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in plugins/integrations/skills/google-apps-script of jezweb/claude-skills.

Open the folder on GitHubat commit 64965d9

Compare with similar skills

Google Apps Script next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Google Apps Script compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Google Apps Script this skilljezweb/claude-skills1.1k—~4.7kAutomated safety check: PassMIT
Google Workspacetaracodlabs/aiden849—~1.1kAutomated safety check: PassApache-2.0
Google SheetsCraftOS-dev/CraftBot392—~3.1kAutomated safety check: PassMIT
MarkitdownImCa0/just-laws78114 repos~3.2kAutomated safety check: NotesMIT
Managing Google Workspacetaylorwilsdon/google_workspace_mcp3.3k—~2.9kAutomated safety check: PassMIT
Instrument Data To Allotropeaws-samples/amazon-bedrock-agents-healthcare-lifesciences2742 repos~2.7kAutomated safety check: PassApache-2.0

Similar skills

  • Google Workspace

    taracodlabs/aiden

    Gmail, Calendar, Drive, Sheets, Docs via Google API (SA / OAuth)

    849 GitHub stars~1.1k tokensUpdated 24 days ago
    Documents & OfficeAuto-check passed
  • Google Sheets

    CraftOS-dev/CraftBot

    Google Sheets API integration with managed OAuth. An agent skill from CraftOS-dev/CraftBot.

    392 GitHub stars~3.1k tokensUpdated today
    Documents & OfficeAuto-check passed
  • Markitdown

    ImCa0/just-laws

    Convert files and office documents to Markdown. An agent skill from ImCa0/just-laws.

    781 GitHub starsUsed in 14 repos~3.2k tokens
    Documents & OfficeAuto-check: notes
  • Managing Google Workspace

    taylorwilsdon/google_workspace_mcp

    Manages Google Workspace operations across 12 services (Gmail, Drive, Calendar, Docs, Sheets, Slides, Forms, Tasks, Contacts, Chat, Apps Script, Custom Search).

    3.3k GitHub stars~2.9k tokensUpdated today
    Documents & OfficeAuto-check passed
  • Instrument Data To Allotrope

    aws-samples/amazon-bedrock-agents-healthcare-lifesciences

    Official

    Convert laboratory instrument output files (PDF, CSV, Excel, TXT) to Allotrope Simple Model (ASM) JSON format or flattened 2D CSV.

    274 GitHub starsUsed in 2 repos~2.7k tokens
    Documents & OfficeAuto-check passed
  • Jev SEO

    AgriciDaniel/jev-seo

    Full live SEO audit of any website from its homepage URL, powered by Jev (TypeSafe's System One model).

    515 GitHub stars~2.5k tokensUpdated 15 days ago
    Documents & OfficeAuto-check: notes

More from jezweb/claude-skills

All 52 skills in this repo
  • Elevenlabs Agents

    jezweb/claude-skills

    Build conversational AI voice agents on the ElevenLabs platform.

    1.1k GitHub starsUsed in 1 repo~3.3k tokens
    Auto-check passed
  • Favicon Gen

    jezweb/claude-skills

    Generate custom favicons from logos, text, or brand colours.

    1.1k GitHub starsUsed in 1 repo~1k tokens
    Auto-check passed
  • Tailwind Theme Builder

    jezweb/claude-skills

    Set up Tailwind v4 + shadcn/ui themed UI with dark mode. An agent skill from jezweb/claude-skills.

    1.1k GitHub starsUsed in 1 repo~3.2k tokens
    Auto-check passed
  • Responsiveness Check

    jezweb/claude-skills

    Test website responsiveness across viewport widths using browser automation.

    1.1k GitHub starsUsed in 1 repo~1.7k tokens
    Auto-check passed
  • MCP Builder

    jezweb/claude-skills

    Build MCP servers in Python with FastMCP. An agent skill from jezweb/claude-skills.

    1.1k GitHub stars~3.1k tokensUpdated yesterday
    Auto-check: notes
  • UX Compare

    jezweb/claude-skills

    Compare UX patterns across multiple reference apps using pattern libraries produced by ux-extract.

    1.1k GitHub starsUsed in 1 repo~2.2k tokens
    Auto-check passed

Works with

Questions about Google Apps Script

What does Google Apps Script do?

Build Google Apps Script automation for Sheets and Workspace. Google Apps Script is an agent skill from jezweb/claude-skills. Build Google Apps Script automation for Sheets and Workspace.

When should I use Google Apps Script?

Google Apps Script fits situations like: (onEdit / time-driven / form submit); the user wants to automate a Google Sheet; build a Sheets menu / sidebar / dialog; hit a Sheets row from email.

How do I install Google Apps Script in Claude Code?

Run `npx skills add jezweb/claude-skills --skill google-apps-script -a claude-code`. Or copy the skill folder (plugins/integrations/skills/google-apps-script in jezweb/claude-skills) into .claude/skills/google-apps-script in your project. Claude Code loads it when a task matches its description.

How do I install Google Apps Script in Codex?

Run `npx skills add jezweb/claude-skills --skill google-apps-script -a codex`. Or copy the skill folder (plugins/integrations/skills/google-apps-script in jezweb/claude-skills) into .agents/skills/google-apps-script in your project. Codex loads it when a task matches its description.

Can I use Google Apps Script in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add jezweb/claude-skills --skill google-apps-script -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/google-apps-script, .gemini/skills/google-apps-script, .github/skills/google-apps-script and .opencode/skills/google-apps-script in your project.

What does Google Apps Script need to run?

SKILL.md names no scripts, command-line tools or credentials: Google Apps Script is instructions for the agent only. Compatibility (from SKILL.md): claude-code-only.

Does Google Apps Script access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Google Apps Script safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Google Apps Script use?

Google Apps Script is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Google Apps Script use?

About 4.7k tokens (SKILL.md is roughly 19k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Google Apps Script?

Skills that share tags, products or a category with Google Apps Script: Google Workspace (taracodlabs/aiden, 849 stars), Google Sheets (CraftOS-dev/CraftBot, 392 stars), Markitdown (ImCa0/just-laws, 781 stars) and Managing Google Workspace (taylorwilsdon/google_workspace_mcp, 3.3k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Google Apps Script?

jezweb (a GitHub user) maintains it in jezweb/claude-skills, which has 1,050 GitHub stars. The repository holds 52 skills in this directory. The repository was last updated on October 5, 2026.

Source: jezweb/claude-skills on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.