数人規模のチームには、たいてい専任の情シスがいません。私のところもそうで、Googleスプレッドシートに溜まった業務を自動化する係は、気づけば手が空いている人(=私)でした。GAS(Google Apps Script)を書き足していくうちに、誰も全体像を把握できない「増殖したスクリプト群」ができあがっていたのです。
この記事では、その状態から抜け出すために私が実際に試した 「GAS を実行層、MCP を接続層、Claude Code を指示層に据える」 連携パターンを、コピペできるコード付きでまとめます。RPA製品を新規契約せず、Google Workspace の標準機能と Claude Code だけで小チームの定型業務を回す、という現実的な構成です。
この記事の前提条件
先に前提を明記しておきます。ここが違うと再現できません。
- Google Workspace(無印の Gmail アカウントでも GAS は動きますが、Web App 公開の挙動が一部異なります)
-
Claude Code(MCP クライアントとして利用。Claude Desktop でも同じ
.mcp.jsonの考え方が使えます) -
Node.js 18 以上(MCP サーバーを Node で書くため。
fetchが標準で使える版) - GAS のデプロイに
clasp(Google 公式の CLI)を使うと、コードを Git 管理できて後述の「ブラックボックス化」を避けられます
想定読者は「GAS は書けるが、AI から叩く方法が分からない」小チーム・個人開発者です。
なぜ Google Workspace × Claude Code なのか
私が関わってきた小チームの業務は、そのほとんどが Google Workspace の中で完結していました。受注はスプレッドシート、やり取りは Gmail、資料は Drive。ここに閉じた自動化をするなら、GAS が最短です。
一方で GAS には弱点があります。トリガーの管理が煩雑になり、スクリプトが増えるほど「どれが何をしているか」が分からなくなる こと。私の環境では GAS プロジェクトが10本を超えたあたりで、変更が怖くて誰も触れない状態になりました。
そこで役割を3層に分けます。
| 層 | 役割 | 使うもの |
|---|---|---|
| 指示層 | 自然言語で「何をしたいか」を伝える | Claude Code |
| 接続層 | GAS を安全にツールとして公開する | MCP サーバー(Node) |
| 実行層 | Workspace 上の実処理を行う | GAS Web App |
こうすると、GAS 側は「1機能=1エンドポイント」に薄く保てて、増えても Claude Code から一覧して呼べます。個々の GAS がブラックボックス化しにくくなるのが、実運用で一番効きました。
全体像:GAS → MCP → Claude Code
まず実行層。スプレッドシートの「受注」シートから当日出荷分だけを返す Web App を GAS で書きます。共有シークレット(token)で叩ける相手を絞るのがポイントです。
// コード.gs — 当日出荷分の受注をJSONで返すWeb App
function doGet(e) {
// 共有シークレットで発信元を絞る(誰でも叩けるURLにしない)
const token = PropertiesService.getScriptProperties().getProperty('API_TOKEN');
if (!e.parameter.token || e.parameter.token !== token) {
return ContentService.createTextOutput(
JSON.stringify({ error: 'unauthorized' })
).setMimeType(ContentService.MimeType.JSON);
}
const sheetId = PropertiesService.getScriptProperties().getProperty('SHEET_ID');
const sheet = SpreadsheetApp.openById(sheetId).getSheetByName('受注');
const rows = sheet.getDataRange().getValues();
const header = rows.shift();
const today = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy-MM-dd');
const items = rows
.map(r => Object.fromEntries(header.map((h, i) => [h, r[i]])))
.filter(o => Utilities.formatDate(
new Date(o['出荷予定日']), 'Asia/Tokyo', 'yyyy-MM-dd') === today);
return ContentService.createTextOutput(
JSON.stringify({ date: today, count: items.length, items })
).setMimeType(ContentService.MimeType.JSON);
}
デプロイは「新しいデプロイ → 種類:ウェブアプリ」で行い、API_TOKEN と SHEET_ID はスクリプトプロパティに入れます。コードに直書きしないのは、clasp で Git 管理したときにシークレットを漏らさないためです。
次に接続層。この Web App を Claude Code のツールとして見せる最小の MCP サーバーです。
// gas-mcp/index.js — GAS Web App を Claude Code のツールにする最小MCPサーバー
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const GAS_URL = process.env.GAS_WEBAPP_URL; // GASのデプロイURL(/exec)
const TOKEN = process.env.GAS_TOKEN; // doGetと同じ共有シークレット
const server = new McpServer({ name: "gas-workspace", version: "1.0.0" });
server.tool(
"get_todays_orders",
"本日出荷分の受注一覧をGoogleスプレッドシートから取得する",
{},
async () => {
const res = await fetch(`${GAS_URL}?token=${encodeURIComponent(TOKEN)}`);
const data = await res.json();
return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
}
);
await server.connect(new StdioServerTransport());
最後に指示層。プロジェクトルートの .mcp.json にこのサーバーを登録すれば、Claude Code から get_todays_orders が呼べます。
{
"mcpServers": {
"gas-workspace": {
"command": "node",
"args": ["./gas-mcp/index.js"],
"env": {
"GAS_WEBAPP_URL": "https://script.google.com/macros/s/xxxxx/exec",
"GAS_TOKEN": "put-your-shared-secret-here"
}
}
}
}
あとは Claude Code に「今日の出荷分をまとめて」と話しかけるだけ。ツール定義の説明文を丁寧に書いておくと、AI がいつ呼ぶべきかを取り違えません。この「1機能を1ツールとして薄く公開する」型を、以下の業務で横展開していきます。
パターン1:スプレッドシート集計とメール報告をなくす
最初に自動化したのは、毎日のルーティンでした。私の場合、スプレッドシートの受注一覧から条件に合う案件を抽出し、関係者にメール報告する作業を毎日20分かけて手でやっていました。1日20分でも、月に積むと約7時間です。
これを GAS の条件フィルタリング+Gmail 送信で書き、毎朝8時のトリガーで回すようにしました。結果、毎日20分の手作業がゼロになり、月約7時間が丸ごと浮きました。レポートのフォーマットも自動で揃うので、「先月と書式が違う」といった細かい手戻りも消えました。
ここで Claude Code を噛ませる意味は、「抽出条件を変えたい」ときにコードを直接いじらずに済む ことです。「今週は出荷予定日が3日以内のものだけにして」と話すと、Claude Code が GAS 側のパラメータ付き呼び出しに翻訳してくれます。条件が固定なら素の GAS で十分ですが、条件が揺れる業務ほど指示層の恩恵が出ます。
パターン2:スプレッドシートのデータから帳票を生成する
次は帳票です。以前は請求書作成が Excel の手入力で、20件で毎月3時間、入力ミスも月に2〜3件出ていました。これを、顧客マスタと売上データ(スプレッドシート)から請求書PDFを自動生成する仕組みに置き換えたところ、3時間が5分に、入力ミスは月2〜3件からゼロ になりました。月末の残業が実質消えたのが一番の変化でした。
GAS なら Google ドキュメントをテンプレートにして、プレースホルダを差し替えて PDF 化 → Drive の指定フォルダに保存、という流れが標準機能だけで組めます。Claude Code からは「10月分の請求書を全部生成して、未送付フォルダに入れて」と頼めば、生成対象の抽出から保存先の振り分けまで一気通貫で走ります。
ポイントは、金額の計算そのものはスプレッドシート側の数式に残す こと。計算ロジックを AI や GAS に散らすと検証しづらくなります。数字は人が検算できる場所に置き、AI には「集めて・整形して・置く」を任せるのが安全な線引きでした。
パターン3:Drive のファイル整理をルールで一括処理する
地味ですが効果が大きかったのが Drive の整理です。共有フォルダに10万件以上のファイルが溜まり、命名規則がバラバラで目的のファイルが見つからない。「あのファイルどこ?」が1日5回は飛んでいました。
命名規則を決めて、既存ファイルをスクリプトで一括リネーム、フォルダも「年度/部門/カテゴリ」の3階層に統一しました。結果、ファイル検索が平均5分から30秒に。Claude Code からは「先月アップされた命名規則違反のファイルを一覧して、正しい名前の案を出して」と使うと、リネーム前の確認までAIに下書きさせられます。
ここでの学びは、ファイル管理はルールを決めるだけでは効かず、既存ファイルまで一括適用して初めて実効性が出る ことです。新規分だけ整えても、探すときに引っかかるのは過去分なので。
パターン4:バラけたデータを横断させる
小チームでも、営業がSFA、経理が会計ソフト、日常はWorkspace、と道具が分かれていきます。私が関わったある現場では顧客情報がサイロ化し、同じ顧客に3回名前を聞くようなことが起きていました。
各サービスの API を使い、顧客IDをキーに横断検索できるハブを作ったところ、1件あたりの情報確認が10分から30秒に短縮されました。Workspace 側(スプレッドシートやDrive)も、GAS Web App を1つのエンドポイントとして同じハブにぶら下げれば、Claude Code から「この顧客の直近のやり取りと請求状況をまとめて」と一括で引けます。
補足すると、社内問い合わせも同じ発想で減らせます。定型質問(有給申請・精算方法など)が問い合わせの7割を占めていた現場では、FAQをナレッジ化して自動応答にしたら、問い合わせが1日30件から9件に減りました。「人が判断すべきものだけ人に回す」設計は、Workspace 上の雑務全般に効きます。
ハマったこと:GAS Web App 特有の落とし穴
正直、ここに辿り着くまでに何度かやり直しました。私がつまずいた点を共有します。
- OAuth スコープの追加漏れで403:GAS 側で新しいサービス(Gmail送信・Drive操作)を使い始めたのにデプロイを更新せず、権限不足で弾かれる。スコープを増やしたら必ず再デプロイが必要です。
- 「アクセスできるユーザー」を全員にしかけた:Web App 公開時のこの設定を安易に「全員」にすると、URLを知る誰でも叩けます。私は token 認証を doGet に入れて、公開範囲は絞る方針にしました(トークンはURLに載るので万全ではありません。機微なデータを扱うならOAuthなど別の認可方式を検討してください)。
-
デプロイURLが変わる罠:「デプロイを管理」から既存デプロイを編集せず新規作成すると
/execのURLが変わり、.mcp.json側が古いURLのまま動かなくなる。既存デプロイのバージョン更新で回すのが安全です。 -
同時実行のレート:トリガーとMCP経由の呼び出しが重なると GAS の実行上限に触れることがある。重い集計は GAS 側でキャッシュ(
CacheService)を挟むと安定しました。
業務→サービス→パターン 早見表
どの業務をどう当てはめるか、私が使っている対応表です。コピペしてチームの実態に合わせて埋めてください。
| 業務 | Workspaceサービス | GASでやること | Claude Codeからの指示例 |
|---|---|---|---|
| 定型集計・報告 | Sheets + Gmail | 抽出→整形→送信、朝のトリガー | 「今週分の集計をメール下書きにして」 |
| 帳票生成 | Sheets + Docs + Drive | テンプレ差込→PDF→フォルダ保存 | 「今月分の請求書を全部生成して」 |
| ファイル整理 | Drive | 命名規則チェック→一括リネーム | 「規則違反のファイルと修正案を出して」 |
| データ横断 | Sheets + 外部API | エンドポイント集約 | 「この顧客の状況をまとめて」 |
| 問い合わせ対応 | Chat / Forms | FAQ照合→定型回答 | 「未回答の質問だけ一覧して」 |
導入順としては、毎日繰り返す・人がやる意味が薄い作業(パターン1)から着手するのがコスパ最良でした。効果が数字で見えると、チームの協力も得やすくなります。
まとめ
- GAS を「実行層」、MCP を「接続層」、Claude Code を「指示層」に3分割すると、GAS が薄く保てて増えても破綻しにくい
- 公開は token 認証+スコープ最小で。Web App の設定と再デプロイの罠に注意
- 数字の計算はスプレッドシートに残し、AI には「集めて・整形して・置く」を任せる
結局のところ、今回いちばん効いたのは派手なAI活用ではなく、「1機能を1エンドポイントに薄く切り出し、それを Claude Code から呼べる形に揃えた」 という地味な整理でした。私のチームでは、これで増殖していた GAS が「触れるスクリプト」に戻り、毎日20分・月3時間といった小さな時間が着実に返ってきています。専任の情シスがいない小チームこそ、手持ちの Google Workspace と Claude Code だけで十分に戦えると感じています。
正直に言うと、私も GAS のデプロイ設定とスコープ周りで何度か403を踏んで遠回りしました。同じところでハマっている人が、この記事で少しでも近道できたら書いた甲斐があります。「うちはこのサービスをこう繋いだ」「この落とし穴は別の回避策がある」といった話があれば、ぜひコメントで共有してください。