AIでエクセルやスプレッドシートに直接アクセスする際、最大の課題は **トークン消費の非効率性** です。表の構造を把握するために全セルにアクセスする必要があり、AIが使用できるトークン数を無駄に消費してしまいます。
この問題を解決する鍵は、**事前のスキーマ定義** にあります。Google Sheets のデータを Google Cloud BigQuery? の **外部テーブル** として読み込むことで、シートを SQL テーブルのように扱えるようになります。外部テーブル作成時にスキーマを定義すれば、シート認識処理の負荷を大幅に軽減できます。
さらにデータ抽出は汎用的な SQL で実行できるため、以下のメリットが得られます:
今回は、プロジェクト管理の WBS を Google Sheets で管理している前提で、Google がオープンソースでリリースした **MCP Toolbox for Databases** を活用し、BigQuery? を介してスプレッドシートを SQL データベースのように効率的に操作できるかを検証します。
このツールにより、Google Sheets のデータを BigQuery? 外部テーブルに読み込み、MCP 経由で AI からクエリを発行することで、定義済みシートに対するトークン消費を大幅に削減できます。
進め方としては、BigQuery?でSQLを使ってスプレッドシートをある程度操作できるようになったら、この **MCP Toolbox for Databases**にツールとして登録すると、AIが代わりにやってくれるようにすることができるという感じです。
GitHub? リポジトリ: https://github.com/googleapis/genai-toolbox
Google Sheets で WBS(Work Breakdown Structure)を管理し、SQL でタスクを効率的に操作します。今回は Sheets を直接扱うのではなく、Sheets のデータを **BigQuery? 外部テーブル** として取り込みます。
公開用のひな形シートはこちらです(右側に2ヶ月分のガントチャート付き): https://docs.google.com/spreadsheets/d/13x7TnzwSTLSsBcJnoYyZkv3fejU-0ktQqspiqmRt4j8/edit?usp=sharing
行3: ヘッダー(B列〜O列) 行4〜: データ開始
カラム構成: B列: スプリント C列: プライオリティ D列: タスクの区分 E列: カテゴリ F列: 概要 G列: 詳細(1件単位で記入) H列: 担当者 I列: 予想作業日数 J列: ステータス K列: 完了日 L列: 予想開始日 M列: 予想終了日 N列: Issue/議事録 O列: 備考
Google Sheets の各列を次のように BigQuery? フィールド名へマッピングします。外部テーブル作成時にこのスキーマを手動定義します。
| シート列 | BigQuery?フィールド名 | 説明 |
| --- | --- | --- |
| B | sprint | スプリント名 |
| C | priority | プライオリティ |
| D | task_type | タスクの区分 |
| E | category | カテゴリ |
| F | summary | 概要 |
| G | description | 詳細 |
| H | assignee | 担当者 |
| I | estimated_days | 予想作業日数 |
| J | status | ステータス |
| K | completed_date | 完了日 |
| L | estimated_start_date | 予想開始日 |
| M | estimated_end_date | 予想終了日 |
| N | issue_url | Issue/議事録リンク |
| O | notes | 備考 |
今回は Docker Compose を利用して MCP サーバーを起動します。ディレクトリ構成やスクリプトは従来とほぼ同じですが、BigQuery? 用の設定ファイルを配置します。
services:
genai-toolbox:
# 最新バージョンに更新
image: us-central1-docker.pkg.dev/database-toolbox/toolbox/toolbox:0.11.0
container_name: genai-toolbox
ports:
- "5000:5000"
volumes:
# ファイルマウントを確実に
- "./tools.yaml:/app/tools.yaml:ro"
- "./credentials.json:/app/credentials.json:ro"
- "./logs:/app/logs"
environment:
- GOOGLE_APPLICATION_CREDENTIALS=/app/credentials.json
command: [
"--tools-file", "/app/tools.yaml",
"--port", "5000",
"--address", "0.0.0.0",
"--log-level", "DEBUG"
]
restart: unless-stopped
networks:
- genai-network
networks:
genai-network: driver: bridge
https://googleapis.github.io/genai-toolbox/resources/tools/bigquery/
まだ未検証です。
# tools.yaml - MCP Toolbox for Databases WBS管理設定
# プロジェクトマネージャー用 BigQuery? WBS管理
sources:
bigquery_wbs:
kind: "bigquery"
project: "${GOOGLE_CLOUD_PROJECT}" # エラーです。
location: "US"
# credentials_path は不要(環境変数 GOOGLE_APPLICATION_CREDENTIALS を利用)
tools:
# 1. WBS全体概要取得
get_wbs_overview:
kind: bigquery-sql
description: "プロジェクトのスプリント別進捗概要を表示します"
source: bigquery_wbs
statement: |
WITH wbs_data AS (
SELECT
CAST(sprint AS STRING) as sprint,
CAST(priority AS STRING) as priority,
CAST(task_type AS STRING) as task_type,
CAST(category AS STRING) as category,
CAST(summary AS STRING) as summary,
CAST(description AS STRING) as description,
CAST(assignee AS STRING) as assignee,
CAST(estimated_days AS FLOAT64) as estimated_days,
CAST(status AS STRING) as status,
CAST(completed_date AS DATE) as completed_date,
CAST(estimated_start_date AS DATE) as estimated_start_date,
CAST(estimated_end_date AS DATE) as estimated_end_date,
CAST(issue_url AS STRING) as issue_url,
CAST(notes AS STRING) as notes
FROM `${GOOGLE_CLOUD_PROJECT}.pm_agent.wbs01`
WHERE sprint IS NOT NULL AND sprint != ''
)
SELECT
sprint,
COUNT(*) as total_tasks,
COUNTIF(status = '完了') as completed_tasks,
ROUND(COUNTIF(status = '完了') * 100.0 / COUNT(*), 1) as completion_rate,
SUM(estimated_days) as total_estimated_days,
COUNT(DISTINCT assignee) as assignee_count
FROM wbs_data
GROUP BY sprint
ORDER BY sprint
(以下、他のツール定義も同様に続く...)
databases:
wbs_bigquery: type: "bigquery" project_id: "obsidian-460615" dataset: "pm_agent" location: "US" credentials_path: "/app/credentials.json"
mcp:
server: name: "wbs-manager" version: "1.0.0"
security:
allowed_operations: ["SELECT", "INSERT", "UPDATE"] row_limit: 1000
@echo off echo Starting MCP Toolbox for Databases... docker-compose pull docker-compose up -d echo MCP Toolbox is running on http://localhost:8080 pause
BigQuery? 外部テーブルを経由すれば、通常のテーブルと同様に SQL を実行できます。
SELECT
summary, assignee, status, estimated_days, estimated_end_date
FROM `obsidian-460615.pm_agent.wbs01` WHERE status IN ('進行中', '開始済み') ORDER BY estimated_end_date ASC;
SELECT
assignee, COUNT(*) as task_count, SUM(estimated_days) as total_days, AVG(estimated_days) as avg_days
FROM `obsidian-460615.pm_agent.wbs01` WHERE status != '完了' GROUP BY assignee ORDER BY total_days DESC;
SELECT
sprint, COUNT(*) as total_tasks, SUM(CASE WHEN status = '完了' THEN 1 ELSE 0 END) as completed_tasks, ROUND(SUM(CASE WHEN status = '完了' THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 1) as completion_rate
FROM `obsidian-460615.pm_agent.wbs01` GROUP BY sprint ORDER BY sprint;
SELECT
summary, assignee, estimated_end_date, DATE_DIFF(estimated_end_date, CURRENT_DATE(), DAY) as days_until_deadline
FROM `obsidian-460615.pm_agent.wbs01` WHERE status != '完了'
AND DATE_DIFF(estimated_end_date, CURRENT_DATE(), DAY) <= 7
ORDER BY estimated_end_date ASC;
curl http://localhost:5000/api/toolset
@modelcontextprotocol/inspector は Google が公開している **MCP サーバー向けの汎用的な検証ツール**です。これを使います。NPM パッケージとして配布されており、npx コマンドでインストールせずに実行できます。オプションでCLIとしても実行できます(CLIは今回使わない)。
npx @modelcontextprotocol/inspector
# 表示されたページから `Transport Type` を「STDIO」から「Streamable HTTP」に変更し、URLに `http://127.0.0.1:5000/mcp` を指定して接続
# ブラウザのURLをみると、トークン<YOUR_SESSION_TOKEN>がかいてあるのでメモ
MCP サーバーが起動していれば、Claude Desktop から外部テーブルに対する SQL 操作が可能です。設定ファイルに MCP サーバーのエンドポイント(HTTP 経由など)を登録し、Claude に対して自然言語で問い合わせると、MCP がバックエンドで BigQuery? へクエリを実行して結果を返してくれます。
以上、BigQuery? を活用した新しい構成の全文でした。実際の環境に合わせてパラメータを調整してご利用ください。