Claude Code からGoogleスプレッドシートを扱う経路は、CSV書き出し・Sheets API・MCPサーバーの3つです。毎週・毎月くり返す定型集計を自動化したいなら、選ぶべきはSheets APIをスクリプト側に固定する方式です。読み取りも書き込みも1プロジェクトあたり毎分300リクエスト、1ユーザーあたり毎分60リクエストというクォータが公式に定められており(Google「Usage limits|Google Sheets API」)、この上限の内側で動く形に落としておけば、同じ入力から毎回同じ表が出ます。
逆に、対話のたびにClaude Codeへ「今月の売上をシートから集計して」と自然文で頼む運用は、集計軸のずれと再実行不能という2つの問題を必ず起こします。この記事では、集計の仕様をコードとルールファイルに書き出し、Claude Codeを「毎回同じ手順を回す実行役」に変えるまでの7手順を、公式ドキュメントで確認できる範囲の実装だけで組み立てます。

この記事の要点
- Claude Codeとスプレッドシートの接続経路は、CSV書き出し・Sheets API・MCPサーバーの3つ。定型集計はSheets API、探索的な調査はCSV書き出し、社内共通の道具にするならMCPサーバーという住み分けになります。
- Sheets APIの読み取り・書き込みは、いずれも1プロジェクトあたり毎分300リクエスト、1ユーザーあたり毎分60リクエストが上限です。超えると429が返るため、指数バックオフと一括取得を前提に設計します。
- 認証情報はClaude Codeに読ませない場所へ置きます。
~/.claude/settings.jsonのpermissions.denyにRead(./.env)を入れる書き方は公式ドキュメントに例示されています。 - 集計の定義(対象期間・キー列・丸め・除外条件)は会話ではなくコードとCLAUDE.mdへ書き出します。ここを言葉で渡し続ける限り、結果は毎回変わります。
- くり返す作業はSkill化します。プロジェクト用は
.claude/skills/<skill-name>/SKILL.md、個人用は~/.claude/skills/<skill-name>/SKILL.mdに置きます。 - MCPサーバーをチームで共有する場合、プロジェクトスコープの設定は
.mcp.jsonに保存され、バージョン管理経由で配布されます。 - 記事中の運用像は想定モデルであり、特定企業の実測値ではありません。数値を挙げている箇所は公式仕様に基づく上限値です。
対象読者
- 週次・月次でスプレッドシートの集計表を手作業で作り直している、経営企画・経理・営業企画の担当者
- 業務側から「この集計を自動化してほしい」と頼まれた社内エンジニア、情報システム担当者
- Claude Codeは触っているが、外部SaaSのデータをどう安全に読ませるかで止まっている方
読了後にできること
- 3つの接続経路から、自分の業務に合うものを理由付きで選べる
- サービスアカウントの権限をどこまで絞るか、鍵をどこに置くかを決められる
- 集計仕様をコードへ書き出し、同じ入力から同じ表を再生成できる状態にできる
- 429やタイムゾーンずれなど、実装時に必ず当たる詰まりどころを事前に潰せる
スプレッドシート連携の3経路と選び方
まず接続方式を決めます。ここを曖昧にしたまま書き始めると、あとで全部書き直すことになります。
| 経路 | 向いている場面 | 弱点 |
|---|---|---|
| CSV書き出し | 一度きりの調査、シートの構造把握 | 手作業が挟まる。定期実行に向かない |
| Sheets API | 毎週・毎月くり返す定型集計 | 認証設定が必要。クォータ設計が要る |
| MCPサーバー | 複数人・複数プロジェクトで同じ操作を共有 | 導入と配布の手間。権限管理が広くなりやすい |
CSV書き出しは「調査用」と割り切る
シートをCSVでダウンロードし、ローカルのファイルとしてClaude Codeに読ませる方法です。認証もライブラリも要らず、列名や表記ゆれを把握する初回の調査には最速です。ただし人がダウンロードする工程が残るため、定期実行の土台にはなりません。最初の1回だけ使い、構造が分かったらSheets APIへ移行する、という位置づけが現実的です。
Sheets APIが定型集計の本命
定型集計の本命はSheets APIです。読み書きが1つのスクリプトに閉じるため、同じスクリプトを再実行すれば同じ結果が出ます。Claude Codeの役割は「集計する人」ではなく「そのスクリプトを書き、直し、実行する人」に変わります。この記事の手順3以降はこの方式を前提にします。
MCPサーバーは共有の道具にするとき
MCPサーバー方式は、スプレッドシート操作をClaude Codeのツールとして常設する方法です。追加は claude mcp add、確認は claude mcp list、セッション内の管理は /mcp コマンドで行います。スコープは3つあり、--scope project を指定するとプロジェクトルートの .mcp.json に保存され、バージョン管理経由でチームに共有されます(Anthropic「Connect Claude Code to tools via MCP」)。
1人で回す定型集計にMCPサーバーを入れると、設定の手間の割に得るものが少なくなります。逆に、複数の担当者が同じシート群を触る運用に育つ見込みがあるなら、最初からこちらで組む価値があります。配布設計はプラグイン経由の配り方まで含めて管理MCPサーバーの配布手順にまとめてあります。

手順1・2:認証とアクセス範囲を先に決める
コードより先に、権限と鍵の置き場所を決めます。ここを後回しにすると、動くけれど社内に出せないものができあがります。
手順1:サービスアカウントを作り、シート側で共有する
Google Cloud プロジェクトでサービスアカウントを作成し、JSONキーを発行します。作っただけでは対象シートを読めません。スプレッドシートの共有設定で、サービスアカウントのメールアドレスを明示的に共有先へ追加する必要があります。
権限は用途で分けます。集計結果を書き戻すシートだけを編集者、元データのシートは閲覧者にしておくと、事故が起きても元データは壊れません。「とりあえず全部編集者」で始めると、あとから絞り直す作業が発生します。
手順2:鍵をClaude Codeの読み取り範囲から外す
JSONキーはリポジトリに入れません。環境変数で参照し、鍵ファイル自体はプロジェクトの外か、Gitの追跡外に置きます。あわせて、設定ファイルで読み取りを明示的に拒否します。
Claude Codeの設定ファイルは、優先度の高い順に管理設定(managed-settings.json)、コマンドライン(claude --settings)、プロジェクトローカル(.claude/settings.local.json)、共有プロジェクト(.claude/settings.json)、ユーザー(~/.claude/settings.json)の5階層です。公式ドキュメントには、リントとテストの実行を許可しつつ.envの読み取りを止める例が載っています(Anthropic「Settings files and precedence」)。
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": [
"Bash(npm run lint)",
"Bash(npm run test *)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)"
]
}
}
deny と ask のルールは、フォルダを信頼する手順を待たずにすぐ適用されます。一方で permissions.allow はチームメンバーがフォルダを信頼したあとに効きます。共有設定に許可ルールだけ書いて「効かない」と悩むのは、この差が原因です。設定ファイルの階層と書き分けはsettings.jsonの設定ガイドで詳しく扱っています。
手順3:集計仕様をシートではなくコードに書き出す
ここが自動化の成否を分けます。多くの集計表は、担当者の頭の中にしかないルールで作られています。
言葉にしないと再現できない4項目
最低限、次の4つを文章にします。
- 対象期間の定義(締め日はいつか、月末が土日のときどうするか)
- キー列(何と何が一致したら同じ取引とみなすか)
- 丸めと単位(円か千円か、小数は切り捨てか四捨五入か)
- 除外条件(テスト行、キャンセル行、社内取引をどう扱うか)
この4項目が決まっていない状態でClaude Codeに「集計して」と頼むと、モデルは妥当そうな解釈を毎回選び直します。結果として、先月と今月で数字の意味が変わります。
CLAUDE.mdに置いて毎回読ませる
決めた仕様はプロジェクトのCLAUDE.mdへ書きます。会話の中で伝えた内容はセッションが変われば消えますが、CLAUDE.mdに書いた内容は毎回読み込まれます。「売上は税抜」「キャンセル行はstatusがcanceledのもの」といった判断を、日本語の箇条書きで置いておくだけで、生成されるコードのぶれが目に見えて減ります。
同じ考え方をExcel側に適用した実装はExcel業務の自動化ガイドにまとめています。ファイル形式が違っても、仕様を外に出すという原則は共通です。

手順4・5:取得と整形をスクリプトに固定する
仕様が決まったら、取得と整形を1本のスクリプトにします。Claude Codeにはこのスクリプトを書かせ、直させ、実行させます。
手順4:一括取得でリクエスト数を減らす
Sheets APIは、範囲ごとに1回ずつ呼ぶとすぐリクエスト数が膨らみます。複数範囲をまとめて取るbatchGetを使えば、1回の呼び出しで済みます。
import os
from google.oauth2 import service_account
from googleapiclient.discovery import build
SCOPES = ["https://www.googleapis.com/auth/spreadsheets.readonly"]
SPREADSHEET_ID = os.environ["SALES_SHEET_ID"]
creds = service_account.Credentials.from_service_account_file(
os.environ["GOOGLE_APPLICATION_CREDENTIALS"], scopes=SCOPES
)
service = build("sheets", "v4", credentials=creds)
result = (
service.spreadsheets()
.values()
.batchGet(
spreadsheetId=SPREADSHEET_ID,
ranges=["拠点A!A1:H", "拠点B!A1:H", "拠点C!A1:H"],
valueRenderOption="UNFORMATTED_VALUE",
)
.execute()
)
for value_range in result["valueRanges"]:
print(value_range["range"], len(value_range.get("values", [])))
valueRenderOption を UNFORMATTED_VALUE にしている点が実務上は重要です。既定の表示値のまま取ると、シート側の表示形式に引きずられて「1,234」という文字列や「¥1,234」が返り、数値として扱えません。表示形式は人間のためのもので、集計には邪魔になります。
手順5:429を前提に指数バックオフを入れる
読み取りの上限は1プロジェクトあたり毎分300リクエスト、1ユーザーあたり毎分60リクエストです。上限を超えたリクエストには 429: Too many requests が返り、公式ドキュメントは指数バックオフでの再試行を推奨しています。拠点数やシート数が増えると、想定より早くこの壁に当たります。
import random
import time
from googleapiclient.errors import HttpError
def call_with_backoff(request, max_retries=5):
for attempt in range(max_retries):
try:
return request.execute()
except HttpError as error:
if error.resp.status != 429 or attempt == max_retries - 1:
raise
wait = (2 ** attempt) + random.random()
time.sleep(wait)
ここで大事なのは、再試行の秒数を固定値にしないことです。複数の処理が同時に上限へ当たると、固定待ちでは同じタイミングで再突入して同じ結果になります。乱数を足して分散させます。
整形は「読める中間ファイル」を必ず残す
取得したデータは、集計する前に一度CSVかParquetで中間ファイルとして書き出します。数字が合わないとき、原因が取得側か集計側かをこのファイルで切り分けられます。中間ファイルを残さない実装は、デバッグのたびにAPIを叩き直すことになり、その分だけクォータを消費します。

手順6:差分と異常を人が見る形にする
自動化した集計を信じてよいかどうかは、出力の隣に置く点検項目で決まります。
出力と一緒に出す4つの点検値
- 前期間比(金額と件数の両方。件数が動かず金額だけ倍になっていれば、単位ゆれを疑う)
- 欠損行数(キー列が空の行が何行あったか)
- 重複キー数(同じキーが2回以上出た件数)
- 除外行数(除外条件に当たって落とした行数)
この4つを集計表の下に出しておくと、異常が起きた回だけ人が確認すれば済みます。逆にこれがないと、毎回全行を目視することになり、自動化した意味が薄れます。月次の突合を扱う考え方は月次決算・残高照合の実装パターンと共通です。
書き戻し先は別シートに分ける
集計結果を元データと同じシートに書き戻すと、次回の取得で自分の出力を読み込む事故が起きます。書き戻し用のシートは別に用意し、サービスアカウントの編集権限もそのシートだけに付けます。
手順7:定期実行とSkill化でくり返しを固定する
最後に、この一連の作業を「毎回同じ手順」に固定します。
Skillとして置く
くり返す作業はSkillにします。個人用は ~/.claude/skills/<skill-name>/SKILL.md、プロジェクト用は .claude/skills/<skill-name>/SKILL.md に置きます。プロジェクト用をコミットすれば、チームの全員が同じ手順を使えます。フロントマターの各項目は任意ですが、Claudeがいつ使うかを判断できるよう description を書くことが推奨されています。また、先頭行が --- でないとフロントマターとして読まれず、ファイル全体が本文として扱われます(Anthropic「Extend Claude with Skills」)。
---
name: sheets-weekly-aggregation
description: 週次の拠点別売上をSheets APIで取得し、点検値付きの集計表を書き戻す
---
1. `scripts/fetch_sales.py` を実行して中間ファイルを作る
2. 前期間比・欠損行数・重複キー数・除外行数を計算する
3. 書き戻し用シートへ出力し、差分だけを報告する
スケジュール実行はスクリプト側に寄せる
定期実行はcronなどのスケジューラからPythonスクリプトを直接叩く形にして、Claude Codeは開発と障害対応に使う、という分け方が安定します。生成の揺れが入る余地を、定期実行の経路から外すという考え方です。バッチ実行の組み方はバッチ処理・定期実行の実践ガイドを参照してください。

想定モデル:3拠点の週次売上集計
ここから先は、公開情報と公式仕様をもとに組み立てた想定モデルです。特定企業の実測値ではありません。
前提として置く状況
拠点A・拠点B・拠点Cがそれぞれ別シートに販売実績を入力し、本部の担当者が毎週月曜に1枚の表へまとめている、という前提を置きます。手作業では、3枚のシートを開き、期間で絞り、コピーして貼り、単位をそろえ、前週比を計算する、という工程が並びます。
7手順に載せ替えるとどうなるか
この構成をここまでの7手順に載せると、次のようになります。取得はbatchGetで3範囲を1回。中間ファイルに書き出したうえで、キー列を「拠点コード+伝票番号」に固定し、statusがcanceledの行を除外。金額は税抜・円単位で保持し、表示のときだけ千円に丸めます。出力の下に前期間比、欠損行数、重複キー数、除外行数の4値を並べ、担当者はそこだけを見ます。
この形にしたときの実際の短縮幅は、シートの汚れ方(表記ゆれ、結合セル、手入力の混在)に強く依存します。初回は仕様の言語化とデータ整備に時間がかかり、2回目以降に効いてくる、という順序で考えるほうが現実に近くなります。
つまずきやすい5点
結合セルが混ざっている
見出し行が結合されていると、取得した配列の列数が行ごとに変わります。結合を外すか、ヘッダー行を固定の1行に作り直すのが先です。コード側で吸収しようとすると、条件分岐が増え続けます。
タイムゾーンがずれる
スプレッドシートのファイル設定のタイムゾーンと、スクリプトを動かすサーバーのタイムゾーンが違うと、締め日前後の1日がずれます。集計対象の日付は、シートの値をそのまま日付文字列として扱い、サーバー時刻からは切り離すのが安全です。
表示形式のせいで数値が文字列になる
前述のとおり valueRenderOption を UNFORMATTED_VALUE にします。ここを既定のままにしていると、合計だけが不自然に小さくなり、原因の特定に時間がかかります。
権限を広く取りすぎる
サービスアカウントに編集権限を広く与えると、生成されたコードの不具合が元データの破壊につながります。読み取り専用スコープ(spreadsheets.readonly)で組めるところは、そのスコープのまま動かします。権限設計そのものの考え方は権限設計ガイドにまとめてあります。
仕様変更がシート側で先に起きる
現場が列を1つ増やしたその週から、集計が静かに壊れます。ヘッダー行の列名を毎回検証し、想定と違えば処理を止めて通知する、という防御を最初から入れておきます。動いてしまうより、止まったほうが被害は小さくなります。
よくある質問
Claude Codeの言語をスプレッドシート操作でも日本語にそろえられますか
Claude Code自体の応答言語は、CLAUDE.mdに日本語で回答する旨を書いておけば実務上ほぼそろいます。ただし、この記事で扱っている集計の正しさとは別の話です。応答が日本語でも、集計仕様が言語化されていなければ結果はぶれます。優先すべきは仕様の言語化のほうです。
MCPサーバーとSheets API直叩き、どちらから始めるべきですか
1人で回す定型集計ならSheets APIの直叩きから始めるのが早いです。スクリプト1本で完結し、再現性も担保できます。複数の担当者が同じシート群を日常的に触るようになった段階で、MCPサーバー化を検討します。移行時も集計ロジックはスクリプトに残るので、作り直しにはなりません。
毎分300リクエストの上限は、実務でどのくらい問題になりますか
範囲ごとに個別取得している実装では、拠点数とシート数の掛け算でリクエストが増えるため、数十拠点規模で当たり始めます。batchGetで一括取得し、中間ファイルを再利用してAPIの再呼び出しを避ければ、通常の月次・週次集計で上限に触れることはまれです。
サービスアカウントの鍵は、どこに置くのが現実的ですか
リポジトリの外に置き、環境変数のパスで参照する形が最も単純です。あわせて permissions.deny で .env 系の読み取りを止めます。シークレット管理の選択肢はシークレット管理の7原則で整理しています。
生成されたスクリプトが正しいかを、どう確かめればよいですか
手作業で作った過去の集計表を1回分だけ正解データとして用意し、同じ期間でスクリプトを走らせて突合します。金額と件数の両方が一致することを確認できれば、以降の実行は点検4値の監視に切り替えられます。
参考・出典
- Anthropic「Connect Claude Code to tools via MCP」(
claude mcp addのスコープ、.mcp.jsonの保存先、/mcpコマンド) - Anthropic「Extend Claude with Skills」(
~/.claude/skills/<skill-name>/SKILL.mdと.claude/skills/<skill-name>/SKILL.md、フロントマターの扱い) - Anthropic「Settings files and precedence」(設定ファイルの5階層、
permissions.allow/permissions.denyの例、trust の適用差) - Google「Usage limits|Google Sheets API」(読み取り・書き込みとも1プロジェクトあたり毎分300リクエスト、1ユーザーあたり毎分60リクエスト、429時の指数バックオフ)
- Google「Method: spreadsheets.values.batchGet」(複数範囲の一括取得、
valueRenderOptionの指定)