Claude CodeでGAS開発を進める手順 — claspでローカル編集してpush
Claude CodeでGAS(Google Apps Script)開発はできます。ブラウザのエディタは操作できないので、claspでローカルに作ってpushする手順です。
Claude CodeでGAS(Google Apps Script)の開発はできます。条件は、claspでプロジェクトをローカルに置くことです。GAS側からClaude APIを呼ぶ実装はGASからClaude APIをUrlFetchAppで呼ぶ記事にあります。
GASは本来、ブラウザのscript.google.comエディタにコードを直接入力する仕組みです。Claude Codeが得意なのは、ローカルのファイルを読み書きしてターミナルコマンドを実行することで、ブラウザ内蔵エディタのテキストボックスはその対象外です。オープンソースCLIのclaspでプロジェクトをローカルファイルとして扱えば、Claude Codeはいつもの手順でコードを書き、clasp pushでGoogleのサーバーへ反映できます。
ローカル開発が前提になる理由と準備するもの
Apps Scriptは、Gmail・Googleカレンダー・ドライブなどWorkspaceアプリ用の組み込みライブラリをあらかじめ備えたプラットフォームです。コードは最新のJavaScriptで書き、インストール作業なしでブラウザ内のエディタから実行できます。スクリプトはユーザーのドライブに保存され、実行自体はGoogleのサーバー側で行われます。
この設計のままでは、ファイルとコマンドを前提にしたClaude Codeの出番がありません。そこでGoogleが公開しているオープンソースCLIclaspを使い、Apps Scriptプロジェクトをローカルのディレクトリとして管理します。clasp pushでドライブへアップロードする仕組みのため、Claude Codeは通常のコーディングと同じ「ファイルを編集してコマンドを実行する」流れでGASを書けます。
Apps Scriptとは、スプレッドシート・ドキュメント・フォームにカスタムメニューやダイアログを追加したり、スプレッドシート専用のカスタム関数やマクロを作ったりできる開発プラットフォームです。ウェブアプリとして公開する、Gmail・カレンダー・AdSenseなど他のGoogleサービスと連携する、Workspace Marketplace向けの軽量なアドオンを作るといった用途にも使えます。
始める前に、次を用意します。clasp 3.4.1はpackage.jsonのenginesでNode.js 20.0.0以上を要求します。
- Node.js 20.0.0以降(
claspはNode.jsで書かれ、npmで配布) - npm
- Googleアカウント(Apps Scriptプロジェクトの保存先になる)
- Apps Script APIの有効化(初回のみ
script.google.com/home/usersettingsから)
ステップ1 claspでプロジェクトを作成する
claspはnpmパッケージとして配布されているので、グローバルインストールしてからログインします。
npm install -g @google/clasp
clasp loginclasp loginはブラウザを開いてGoogleアカウントの認可を求めます。ログインが済めば、以降のコマンドはこのアカウント名義でApps Scriptプロジェクトを操作します。
プロジェクトの作成はclasp createです。--typeでどのGoogleサービスに紐づけるかを指定します。
mkdir sheets-automation && cd sheets-automation
clasp create --type sheets --title "在庫レポート自動化"clasp create --helpでは、--typeの既定値がstandaloneと表示されます。指定できる値はstandalone docs sheets slides forms webapp apiの7種類です。docs sheets slides formsを選ぶと、対応するファイル形式に添付された「コンテナバインド」スクリプトが新規作成されます。既存のスプレッドシートやドキュメントに紐づけたい場合は、--typeを付けずにclasp create --parentId <ファイルID>を使います。ガイドとREADMEの書き方も、この形が前提です。
ただしclasp 3.4.1のソース(create-script.js)では、--type sheetsと併用するとparentIdが読まれません。新しいスプレッドシートが作られ、ドキュメントの説明とは分岐が食い違います。
コマンドを実行すると、カレントディレクトリに2つのファイルが生成されます。スクリプトIDを保存する.clasp.jsonと、プロジェクトメタデータを持つappsscript.json(マニフェスト)です。Claude Codeが編集するのは主にこのマニフェストと、これから追加する.jsファイルになります。
すでにブラウザのエディタで書いたスクリプトをローカルへ持ち出したい場合は、新規作成でなくclasp clone <スクリプトID>を使います。スクリプトIDは、プロジェクトを開いて左の「プロジェクトの設定」を選び、「ID」欄の「スクリプトID」からコピーできます。
ステップ2 Claude Codeにコードを書かせる
ファイルが揃えば、あとは通常のコーディングと同じ流れです。要件を自然文で伝えます。
スプレッドシートのB列に入力された在庫数をもとに、
10個未満の行のA列を黄色でハイライトするonEditトリガーを
Code.jsに書いてApps Scriptのランタイムは、SpreadsheetAppやDocumentAppのような組み込みサービスをあらかじめ提供しているため、npmでのパッケージ追加は不要です。Claude Codeが書くコードも通常のGASと同じで、トップレベルに定義した関数がそのままトリガーやカスタム関数として認識されます。
function onEdit(e) {
const range = e.range;
if (range.getColumn() !== 2) return;
const sheet = range.getSheet();
const qty = range.getValue();
sheet.getRange(range.getRow(), 1)
.setBackground(qty < 10 ? "#fff59d" : null);
}承認スコープを明示的に絞りたいときは、appsscript.jsonのoauthScopesにURL文字列で追加します。何も書かなければ、Apps Scriptがコード中の関数呼び出しを走査して、必要なスコープを自動的に決めます。
モダンなconst letやアロー関数を使うには、マニフェストのruntimeVersionに"V8"を指定します。省略すると既定のSTABLEになり、マニフェストのリファレンスはこれを「現状Rhino」と説明しています。DEPRECATED_ES5はV8への自動移行を止めるための値で、これもRhino扱いです。Claude Codeに依頼文を渡すときは「appsscript.jsonのruntimeVersionはV8のまま」と添えておくと、マニフェストの書き換えで退行しにくくなります。
ステップ3 pushしてデプロイ・実行を確認する
コードを保存したら、ローカルからドライブへアップロードします。
clasp push押す前にclasp statusで、pushされるファイルを確認できます。.js .html appsscript.json、サブディレクトリの.js、README.md、.ts、node_modules/が並ぶ構成なら、clasp 3.4.1は次のように分類します。
$ clasp status
Tracked files:
└─ appsscript.json
└─ Code.js
└─ sidebar.html
└─ lib/util.js
Untracked files:
└─ .clasp.json
└─ main.ts
└─ node_modules/
└─ README.mdmain.tsはUntrackedなので、TypeScriptで書かせるときは変換の経路を別に用意します。lib/util.jsのようなサブディレクトリのファイルも送られ、Apps Script側ではファイル名にパスが残ります。TypeScript化とJestでのテストはClaude CodeでGASをTypeScript化する記事にあります。
pushはリモートのプロジェクト全体を、送ったファイルの内容で置き換えます。Google側のscripts APIがファイル単位や不可分な更新に対応していないためで、ブラウザのエディタだけにある変更はpushで消えます。ドット始まりのファイルや、受け付けない拡張子のファイルは送られません。除外を足したいときは.claspignoreに書きます。
clasp push --forceのhelpには「Forcibly overwrites the remote manifest.」とあります。公式のCI手順は、リモートのコードを確認なしで上書きするフラグと説明しています。反映結果はブラウザのApps Scriptエディタでそのまま確認でき、clasp open-scriptで開けます。
スクリプトを初めて実行すると、Googleは承認フローを開始します。コードが要求する権限はOAuthスコープとして、人間が読める文言で示されます。spreadsheets.readonlyなら、承認画面の文言は「View your Google Spreadsheets」です。
Apps Script IDEなど一部の画面では、権限を一括でなく個別に選べる同意画面が出ます。ここで一部を許可しなかった場合や、許可を後から取り消した場合は、トリガーが「Authorization is required to perform that action.」のエラーですぐ失敗します。トリガー設定時にScriptApp.requireScopes(authMode, oAuthScopes)を呼ぶと、必要な権限を先に取らせられます。依頼文に「トリガー設定時にrequireScopesを呼ぶ」と添える手があります。
ウェブアプリやアドオンとして公開する場合は、デプロイします。-Vを付けないclasp deployは、バージョンを自動で作成してからデプロイします。
clasp deploy -d "初回リリース"ガイドは、先にclasp versionで変更不可のバージョンを作る流れです。その場合は-Vでバージョン番号を指定します。
clasp version "初回リリース"
clasp deploy -V 1 -d "初回リリース"clasp versionのあとに引数なしのclasp deployを続けると、バージョンが2つできます。
デプロイの一覧確認はclasp deployments、取り下げにはclasp undeploy <deploymentId>を使います。既存デプロイを新しいバージョンへ差し替えるのがredeployですが、引数の書き方が公式ページとCLI本体で食い違います。
redeployの書式
公式のclaspガイド
clasp redeploy <deploymentId> <version> <description>と、バージョンと説明を位置引数で並べます。clasp deploy [version] [description]も同じ形です。
clasp 3.4.1の--help
clasp redeploy [options] <deploymentId>で、バージョンは-V, --versionNumber、説明は-d, --descriptionです。deployにも同じ2つのオプションと-i, --deploymentIdがあります。
Claude Codeに依頼文でコマンドを書かせるときは、手元でclasp redeploy --helpを見せるか、-V -dの形を例として渡すと取り違えを避けられます。
よくあるつまずき
コンテナバインドとスタンドアロンを混同する: clasp create --type sheetsは新しいスプレッドシートを作ってそこにスクリプトを紐づけます。既存のシートに追加したい場合は、ステップ1のとおり--typeを省いて--parentIdを渡します。
pushは成功したのにコードが変わらない: .clasp.json内のscriptIdが、実際にpushしたいプロジェクトと一致しているか確認します。複数プロジェクトをclasp cloneで切り替えていると起きやすいつまずきです。Webアプリとして公開している場合は、デプロイが指すバージョンも確かめます。版とURLの関係はGASのdoPostでWebhookを受ける手順にあります。
401 Unauthorizedで止まる: 公式のCI手順では、ローカルでclasp loginをやり直し、CLASPRC_JSONのシークレットを更新する対処が示されています。pushのあとに実行時エラーが出たときのログの追い方は、ClaudeでGASのエラーログを調べるにまとめています。
CI/CDではブラウザ認証が使えない: GitHub Actionsのようなターミナルの無い環境では、clasp loginのブラウザOAuthフローが実行できません。clasp --helpには、認証ファイルを渡す-A, --auth <file>と、--adc(環境のApplication Default Credentials)も並びます。READMEは--authを非推奨とし、複数アカウントの使い分けには--user <name>を挙げています。公式のCI手順は、次の流れです。
公式のCI/CD手順(GitHub Actions)
- 1
2つのシークレットを登録する
CLASPRC_JSONに~/.clasprc.jsonの中身、CLASP_JSONに.clasp.jsonの中身(スクリプトIDの対応)を入れます。リフレッシュトークンはApps Scriptプロジェクトへのアクセス権になるため、定期的な入れ替えが推奨されています。 - 2
2つのファイルを.gitignoreに入れる
.clasprc.jsonと.clasp.jsonはコミットしません。公式の手順はこの2つを同列に扱っています。 - 3
mainへのpushで書き出してデプロイする
ワークフロー内で
echo '${{ secrets.CLASPRC_JSON }}' > ~/.clasprc.jsonを実行し、.clasp.jsonにも同じ要領でCLASP_JSONを書き出します。そのあとnpx @google/clasp push --forceを呼び、続けてnpx @google/clasp version "$(git rev-parse --short HEAD)"でコミットIDのバージョンを作ります。PRではnpm run lintだけを回す別ワークフローです。
開発・ステージング・本番を分けたい場合は、環境ごとに別のApps Scriptプロジェクトを作ります。シークレットはCLASP_JSON_DEV CLASP_JSON_STAGING CLASP_JSON_PRODのように、.clasp.json側を環境別に用意します。デプロイするブランチに応じて、.clasp.jsonへ書き込む中身を切り替えます。READMEには別の方法もあります。--project <file>(-P)で.clasp.json以外のファイルを読ませる形で、複数のデプロイ先を想定したオプションです。
CIの症状別の対処は公式に4つ挙がっています。「Script API not enabled」はscript.google.com/home/usersettingsで有効化します。「ENOENT .clasp.json」は、認証情報を書き出すステップがclasp pushより前にあるかを確かめます。「Push succeeds but code unchanged」はシークレットのscriptIdが対象プロジェクトと一致しているかを見ます。残る「401 Unauthorized」の対処は上のとおりです。
スコープの自動検出に頼りすぎる: ほとんどのスクリプトは自動検出で足ります。ただし公開するアドオンは、可能な限り狭いスコープを使う必要があると公式のスコープ解説にあります。読み取りだけならspreadsheetsでなくspreadsheets.readonlyのように、狭いスコープをoauthScopesへ明示します。spreadsheetsは読み書きの両方を含むスコープです。
claspのMCPサーバーでClaude Codeからpushさせる
clasp 3.4.1にはclasp mcp(start-mcp-server)というコマンドがあります。--helpの説明は「Starts an MCP server for interacting with apps script.」です。stdioでtools/listを送ると返るツールは5つで、いずれもdestructiveHintはtrueです。
| ツール | 内容 |
|---|---|
push_files | 内容ローカルのプロジェクトをリモートへpushする |
pull_files | 内容Apps Scriptプロジェクトのファイルをローカルへpullする |
create_project | 内容新しいApps Scriptプロジェクトを作る |
clone_project | 内容既存プロジェクトをローカルへクローンしてpullする |
list_projects | 内容Apps Scriptプロジェクトを一覧する |
list_projectsを除く4つのツールがprojectDir(.clasp.jsonを含むディレクトリ)を受け取ります。version deploy redeployに当たるツールは無いので、公開の手順はCLIを呼ぶ形に残ります。Claude Codeへの登録はREADMEどおり、-y付きのclaude mcp add clasp -- npx -y @google/clasp mcpです。-yが無いと、パッケージ未取得の環境でnpxが確認待ちになり、stdioが止まります。
Claude CodeでGoogleサービスを自動化する他の手段との使い分け
Google Workspaceの自動化にClaude Codeを使う手段は、claspによるローカル開発だけではありません。目的に応じて向き不向きがあります。
| 手段 | おすすめ度 | 理由 |
|---|---|---|
| clasp + Claude Code(本記事) | おすすめ度◎ | 理由トリガーやカスタム関数をコードとして継続的に管理・デプロイしたい場合に向く |
| Apps Scriptエディタで直接編集 | おすすめ度△ | 理由数行の修正で済む単発作業には手早いが、Claude Codeの支援やGitでのレビューは受けられない |
| Claude CodeのChrome連携でDocsに書き込む | おすすめ度○ | 理由ログイン済みのDocsにその場で文章を打ち込みたい、API設定なしの単発ドラフト作成に向く |
| Google CloudのMCPサーバー | おすすめ度△ | 理由Workspaceでなく、BigQueryやCompute EngineなどGCPリソースの操作が目的なら適している |
claspはコードをバージョン管理し、GitHub Actionsで継続的にデプロイできる点がChrome連携との一番の違いです。Chrome連携は認証設定が要らないぶん、思いついた瞬間にDocsへ書き込めます。長い処理が6分で止まる場合の直し方はClaudeでGASの6分制限を分割実行に直す依頼の出し方にあります。フォーム送信をきっかけに動かす処理はClaudeでGASのフォーム送信トリガーを作るにまとめています。「Claude Codeが外部CLIを呼び出してコードとして管理する」という型そのものはant CLIでAPIリソースをスクリプトで自動化するでも扱っており、認証情報の扱い方は共通しています。
まとめ
Apps ScriptをClaude Codeに書かせる出発点は、claspでローカルに持ち出すことです。判断が分かれるのは、pushを手元のCLIで続けるか、clasp mcpで任せるか、CIに移すかの3択で、CIに移したら手動編集をやめます。
参照した一次ソース
この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。