概要
本記事では、DatabricksからGoogle管理のBigQuery MCPサーバーにアクセスし、
BigQueryのデータを取得・分析できるか検証した内容を記載します。
<検証は以下の2パターンで行いました。>
検証A. Databricksノートブックから、Pythonで直接BigQuery MCPサーバーを呼び出す方法
検証B. Databricks Unity CatalogにMCP Serviceとして登録し、Playground上で自然言語からデータ分析を行う方法
Google Cloud側の準備
① テストデータの準備
まず、今回の検証で使用するBQテーブルを作成します。(今回は以下内容で作成)
空テーブル作成
CREATE OR REPLACE TABLE `TEST_DB.MCP_TEST_DATA` (
customer_id STRING OPTIONS(description="顧客ID(システム内部の一意キー)"),
kaiin_id STRING OPTIONS(description="会員ID"),
card_no STRING OPTIONS(description="会員カード番号"),
phone_no STRING OPTIONS(description="電話番号"),
address STRING OPTIONS(description="住所"),
customer_name STRING OPTIONS(description="氏名"),
email STRING OPTIONS(description="メールアドレス"),
birth_date DATE OPTIONS(description="生年月日"),
gender STRING OPTIONS(description="性別"),
postal_code STRING OPTIONS(description="郵便番号"),
prefecture STRING OPTIONS(description="都道府県"),
store_code STRING OPTIONS(description="登録店舗コード"),
membership_rank STRING OPTIONS(description="会員ランク"),
points_balance INT64 OPTIONS(description="保有ポイント"),
registration_date DATE OPTIONS(description="会員登録日"),
last_purchase_date DATE OPTIONS(description="最終購入日"),
status STRING OPTIONS(description="会員ステータス(ACTIVE/INACTIVE)"),
PRIMARY KEY (customer_id) NOT ENFORCED
);
データ挿入
INSERT INTO `TEST_DB.MCP_TEST_DATA`
(customer_id, kaiin_id, card_no, phone_no, address, customer_name, email, birth_date, gender, postal_code, prefecture, store_code, membership_rank, points_balance, registration_date, last_purchase_date, status)
VALUES
('CUST0000001','K10023001','4980123400010001','090-1234-5601','東京都千代田区丸の内1-1-1','佐藤','sato.taro01@example.com','1985-04-12','M','100-0005','東京都','ST001','ゴールド',12500,'2019-06-01','2026-08-01','ACTIVE'),
('CUST0000004','K10023004','4980123400010004','090-1234-5604','愛知県名古屋市中区栄4-4-4','田中','tanaka.misaki04@example.com','1995-02-18','F','460-0008','愛知県','ST004','ゴールド',22100,'2018-09-22','2026-08-10','ACTIVE'),
('CUST0000007','K10023007','4980123400010007','090-1234-5607','宮城県仙台市青葉区一番町7-7-7','山本','yamamoto.daisuke07@example.com','1983-01-27','M','980-0811','宮城県','ST007','ゴールド',18900,'2017-08-19','2026-08-05','ACTIVE'),
('CUST0000002','K10023002','4980123400010002','090-1234-5602','大阪府大阪市北区梅田2-2-2','鈴木','suzuki.hanako02@example.com','1990-07-23','F','530-0001','大阪府','ST002','シルバー',3400,'2020-01-15','2026-07-20','ACTIVE'),
('CUST0000005','K10023005','4980123400010005','090-1234-5605','福岡県福岡市博多区博多駅前5-5-5','伊藤','ito.kenta05@example.com','1988-06-30','M','812-0011','福岡県','ST005','シルバー',5600,'2019-12-01','2026-06-15','ACTIVE'),
('CUST0000008','K10023008','4980123400010008','090-1234-5608','広島県広島市中区紙屋町8-8-8','中村','nakamura.yumi08@example.com','1975-12-03','F','730-0011','広島県','ST008','シルバー',4300,'2020-06-25','2026-04-28','ACTIVE'),
('CUST0000011','K10023011','4980123400010011','090-1234-5611','埼玉県さいたま市大宮区桜木町11-11-11','吉田','yoshida.shota11@example.com','1993-03-16','M','330-0854','埼玉県','ST011','シルバー',3900,'2021-07-08','2026-06-02','ACTIVE'),
('CUST0000014','K10023014','4980123400010014','090-1234-5614','新潟県新潟市中央区古町14-14-14','松本','matsumoto.yoko14@example.com','1980-07-07','F','951-8063','新潟県','ST014','シルバー',5100,'2019-10-02','2026-07-25','ACTIVE'),
('CUST0000017','K10023017','4980123400010017','090-1234-5617','長野県長野市南長野17-17-17','林','hayashi.naoki17@example.com','1979-09-05','M','380-0835','長野県','ST017','シルバー',2800,'2020-08-30','2026-06-22','ACTIVE'),
('CUST0000020','K10023020','4980123400010020','090-1234-5620','石川県金沢市片町20-20-20','山口','yamaguchi.mao20@example.com','1998-01-30','F','920-0981','石川県','ST020','シルバー',3700,'2021-09-19','2026-04-11','ACTIVE'),
('CUST0000003','K10023003','4980123400010003','090-1234-5603','神奈川県横浜市西区みなとみらい3-3-3','高橋','takahashi.ichiro03@example.com','1978-11-05','M','220-0012','神奈川県','ST003','レギュラー',800,'2021-03-10','2026-05-11','ACTIVE'),
('CUST0000006','K10023006','4980123400010006','090-1234-5606','北海道札幌市中央区大通西6-6-6','渡辺','watanabe.sakura06@example.com','1992-09-14','F','060-0042','北海道','ST006','レギュラー',1200,'2022-04-05','2026-07-01','ACTIVE'),
('CUST0000009','K10023009','4980123400010009','090-1234-5609','京都府京都市下京区烏丸通9-9-9','小林','kobayashi.osamu09@example.com','1997-05-09','M','600-8216','京都府','ST009','レギュラー',600,'2023-01-11','2026-03-30','ACTIVE'),
('CUST0000012','K10023012','4980123400010012','090-1234-5612','千葉県千葉市中央区富士見12-12-12','山田','yamada.riko12@example.com','1986-10-11','F','260-0015','千葉県','ST012','レギュラー',950,'2022-11-20','2026-05-19','INACTIVE'),
('CUST0000015','K10023015','4980123400010015','090-1234-5615','岡山県岡山市北区表町15-15-15','井上','inoue.takuya15@example.com','1996-12-19','M','700-0822','岡山県','ST015','レギュラー',400,'2023-05-14','2026-02-10','ACTIVE');
② サービスアカウントの作成
Databricksからアクセスするための、専用サービスアカウントを作成します。
・Cloud Console →「IAMと管理」→「サービスアカウント」→「+サービスアカウントを作成
③ サービスアカウントキーの発行
・サービスアカウントの詳細画面 →「キー」タブ →「キーを追加」→「新しい鍵を作成」→「JSON」
警告
今回は検証目的のため、サービスアカウントキー(JSON)の発行としていますが、本格運用の際はOAuth 2.0 + IAMによる認証が推奨されています。
Databricks側の準備
① サービスアカウントキーをDatabricks Secretsに登録
発行したJSONキーをBase64にエンコードした後、Databricks Secretに登録しています。
JSONをBase64にエンコード
```bash
python -c "import json, base64; print(base64.b64encode(json.dumps(json.load(open('サービスアカウントキー.json'))).encode()).decode())"
```
DatabricksノートブックからSecret Scope作成・登録
import requests
HOST = "https://<ワークスペースURL>"
TOKEN = "<Databricksアクセストークン>"
GCP_SA_KEY_B64 = "<Base64エンコードしたサービスアカウントキー>"
headers = {"Authorization": f"Bearer {TOKEN}"}
# スコープ作成
res = requests.post(
f"{HOST}/api/2.0/secrets/scopes/create",
headers=headers,
json={"scope": "gcp-mcp"},
)
print(f"create-scope: {res.status_code} {res.text}")
# Base64文字列をSecretとして登録
res = requests.post(
f"{HOST}/api/2.0/secrets/put",
headers=headers,
json={
"scope": "gcp-mcp",
"key": "sa-key-json-b64",
"string_value": GCP_SA_KEY_B64,
},
)
print(f"put-secret : {res.status_code} {res.text}")
検証A. Databricksノートブックから、Pythonで直接BigQuery MCPサーバーを呼び出す
Databricksノートブックから、GoogleのマネージドBigQuery MCPサーバーに対して、
HTTP経由で直接アクセスできるかを検証します。
処理構成
- サービスアカウントキーから、Google Cloudの認証情報(
credentials)を作成する - 認証情報から、有効なアクセストークンを取得し、認証ヘッダーを組み立てる
- JSON-RPC形式のペイロードを組み立て、BigQuery MCPサーバーへPOSTリクエストを送る
- レスポンスを検証し、結果をPythonの辞書として返す
設定
# Google側の対象情報
PROJECT_ID = "<PROJECT_ID>"
DATASET_ID = "<DATASET_ID>"
TABLE_ID = "<TABLE_ID>"
MCP_ENDPOINT = "https://bigquery.googleapis.com/mcp"
# Base64→JSON
sa_key_b64 = dbutils.secrets.get(scope="gcp-mcp", key="sa-key-json-b64")
sa_key_json = base64.b64decode(
sa_key_b64.replace("\n", "").replace(" ", "")
).decode("utf-8")
sa_key_info = json.loads(sa_key_json)
# 認証情報の作成
credentials = service_account.Credentials.from_service_account_info(
sa_key_info,
scopes=["https://www.googleapis.com/auth/bigquery"],
)
認証ヘッダーの組み立て
def get_mcp_headers():
auth_req = google.auth.transport.requests.Request()
credentials.refresh(auth_req)
return {
"Content-Type": "application/json",
"Authorization": f"Bearer {credentials.token}",
}
MCPサーバー呼び出し関数(call_mcp)の定義
def call_mcp(method: str, params: dict | None = None) -> dict:
"""BigQuery MCPサーバーへJSON-RPCリクエストを送る。"""
payload = {"jsonrpc": "2.0", "id": "1", "method": method}
if params is not None:
payload["params"] = params
response = requests.post(
MCP_ENDPOINT,
headers=get_mcp_headers(),
data=json.dumps(payload),
timeout=60,
)
response.raise_for_status()
return response.json()
利用可能ツールの確認
BigQuery MCPサーバーに、利用可能なツールの一覧を問い合わせます。
tools_response = call_mcp("tools/list")
print("利用可能なツール:")
for tool in tools_response.get("result", {}).get("tools", []):
print(" -", tool.get("name"))
マネージドBigQuery MCPで用意されているツールの概要は以下の通りです。
| ツール名 | 概要 |
|---|---|
list_dataset_ids |
プロジェクト内のBigQueryデータセットID一覧を取得する |
get_dataset_info |
指定したデータセットのメタデータ(作成日時、説明など)を取得する |
list_table_ids |
指定したデータセット内のテーブルID一覧を取得する |
get_table_info |
指定したテーブルのスキーマ・メタデータを取得する |
execute_sql_readonly |
読み取り専用(SELECT文のみ)でSQLクエリを実行する。INSERT/UPDATE/DELETEは実行不可 |
execute_sql |
SQLクエリを実行する(読み取り・書き込みともに可能) |
クエリの実行
execute_sql_readonlyツールを使って、会員ランク(membership_rank)ごとの
人数と平均保有ポイントを集計してみます。
analysis_query = f"""
SELECT
membership_rank,
COUNT(*) AS customer_count,
AVG(points_balance) AS avg_points_balance
FROM `{PROJECT_ID}.{DATASET_ID}.{TABLE_ID}`
GROUP BY membership_rank
ORDER BY customer_count DESC
"""
query_response = call_mcp(
"tools/call",
params={
"name": "execute_sql_readonly",
"arguments": {
"projectId": PROJECT_ID,
"query": analysis_query,
},
},
)
print(json.dumps(query_response, indent=2, ensure_ascii=False))
実行結果
{
"id": "1",
"jsonrpc": "2.0",
"result": {
"content": [
{
"text": "{\"schema\":{\"fields\":[{\"name\":\"membership_rank\",\"type\":\"STRING\",\"mode\":\"NULLABLE\"},{\"name\":\"customer_count\",\"type\":\"INTEGER\",\"mode\":\"NULLABLE\"},{\"name\":\"avg_points_balance\",\"type\":\"FLOAT\",\"mode\":\"NULLABLE\"}]},\"rows\":[{\"f\":[{\"v\":\"シルバー\"},{\"v\":\"7\"},{\"v\":\"4114.285714285714\"}]},{\"f\":[{\"v\":\"レギュラー\"},{\"v\":\"5\"},{\"v\":\"790.0\"}]},{\"f\":[{\"v\":\"ゴールド\"},{\"v\":\"3\"},{\"v\":\"17833.333333333332\"}]}],\"jobComplete\":true,\"queryId\":\"job_7s4ZRJ1KytDq4m0GjpT2x9KXNGQO\",\"totalBytesBilled\":\"10485760\",\"totalSlotMs\":\"6\",\"totalBytesProcessed\":\"345\"}",
"type": "text"
}
],
"structuredContent": {
"jobComplete": true,
"queryId": "job_7s4ZRJ1KytDq4m0GjpT2x9KXNGQO",
"rows": [
{
"f": [
{
"v": "シルバー"
},
{
"v": "7"
},
{
"v": "4114.285714285714"
}
]
},
{
"f": [
{
"v": "レギュラー"
},
{
"v": "5"
},
{
"v": "790.0"
}
]
},
{
"f": [
{
"v": "ゴールド"
},
{
"v": "3"
},
{
"v": "17833.333333333332"
}
]
}
],
"schema": {
"fields": [
{
"mode": "NULLABLE",
"name": "membership_rank",
"type": "STRING"
},
{
"mode": "NULLABLE",
"name": "customer_count",
"type": "INTEGER"
},
{
"mode": "NULLABLE",
"name": "avg_points_balance",
"type": "FLOAT"
}
]
},
"totalBytesBilled": "10485760",
"totalBytesProcessed": "345",
"totalSlotMs": "6"
}
}
}
テストデータ通り、以下の集計結果が取得できていることが確認できます。
| 会員ランク | 人数 | 平均保有ポイント |
|---|---|---|
| シルバー | 7人 | 4,114 |
| レギュラー | 5人 | 790 |
| ゴールド | 3人 | 17,833 |
検証B.Databricks Unity CatalogにMCP Serviceとして登録し、Playground上で自然言語からデータ分析を行う
Databricksの Unity Catalog にBigQuery MCPサーバーを「MCP Service」として登録し、
Playground上から自然言語でBigQueryのデータを分析できるかを検証します。
手順
- Unity AI Gateway の MCPs 画面から、BigQuery MCPサーバーを新規登録する
- 認証方式を選択し、必要な情報を設定する
- 登録されたツール一覧を確認する
- Playground上で、自然言語によるデータ分析を実行する
① Unity AI Gateway の MCPs 画面から新規登録
Databricksワークスペースの左メニューから「AI Gateway」を開き、上部タブの「MCPs」を選択します。
右上の「+ MCP」ボタンをクリックし、Connect an existing MCP serverを選択します。

登録時に指定する項目は以下の通りです。
| 項目 | 値 |
|---|---|
| Catalog | 任意(例: test_db) |
| Schema | 任意(例: mcp) |
| Name | 任意(例: gcp_mcp) |
| Connection | Create new connection |
| Server URL | https://bigquery.googleapis.com/mcp |
② 認証方式の設定
今回は検証目的なので、Bearer token で認証します。
Databricksノートブックで以下を実行し、アクセストークンを取得します。
import json
import base64
from google.oauth2 import service_account
import google.auth.transport.requests
# Databricks SecretsからBase64エンコードされたサービスアカウントキーを取得
sa_key_b64 = dbutils.secrets.get(scope="gcp-mcp", key="sa-key-json-b64")
sa_key_json = base64.b64decode(
sa_key_b64.replace("\n", "").replace(" ", "")
).decode("utf-8")
sa_key_info = json.loads(sa_key_json)
credentials = service_account.Credentials.from_service_account_info(
sa_key_info,
scopes=["https://www.googleapis.com/auth/bigquery"],
)
# アクセストークンを取得
auth_req = google.auth.transport.requests.Request()
credentials.refresh(auth_req)
print("取得したアクセストークン:")
print(credentials.token)
取得したアクセストークンを、Bearer token欄に貼り付け、Create & load toolsボタンをクリックします。

Create & load toolsボタンをクリックしたら、利用可能なToolの一覧が表示され選択が可能になります

警告
アクセストークンは発行から約1時間で失効するため、更新が必要です。
今回は検証目的のため、アクセストークンでの認証を選択していますが恒久運用にはOAuth系の認証方式への切り替えが必要です。
④ Playgroundでの自然言語分析
Create MCP Serviceで作成後、画面右上のTry in Playgroundをクリックすると、このMCP Serviceのツールを使えるチャット画面が開きます。

以下のように、テーブル情報を含めて自然言語で質問してみます。
プロジェクトID:<PROJECT_ID>のBigQueryのTEST_DBデータセットにあるMCP_TEST_DATAから、会員ランク(membership_rank)ごとの人数を集計してください。
実行すると、使用したToolと結果を含めたやり取りが画面に表示され、
最終的な集計結果が出力されます。


まとめ
DatabricksからGoogle管理のBigQuery MCPサーバーへのアクセスを、2つの方法で検証しました。
検証A. Databricksノートブックから、Pythonで直接BigQuery MCPサーバーを呼び出す方法
検証B. Databricks Unity CatalogにMCP Serviceとして登録し、Playground上で自然言語からデータ分析を行う方法
どちらの方法でも、GoogleのマネージドMCPサーバーに対してBigQueryのデータを取得・分析できることを確認できました。
本番規模のデータに対してエージェントが適切なSQLを自律生成し、適切なToolを使用して分析が行えるかの検証が今後の課題です。



