1. はじめに
AI エージェントからデータベースを使う「MCP でつなぐ」やり方を、いろいろな組み合わせで試してきました。少し前に Google の MCP Toolbox for Databases(以下 MCP Toolbox)を Oracle Autonomous Database に向けて使う記事を書いたので、その AWS 版として、今回は同じ MCP Toolbox を Aurora PostgreSQL に向けて 使ってみます。
ちょうど直前に、AWS 公式の awslabs postgres-mcp-server を同じ Aurora につなぐ検証をやっていました。せっかくなので「同じ Aurora を、別の MCP サーバ(Google の Toolbox)から触るとどう違うか」も、最後に軽く並べてみます。
MCP(Model Context Protocol)は、AI エージェントに外部ツールやデータソースをつなぐための共通プロトコルです。MCP Toolbox は「DB をツールとして MCP に公開する」役割のサーバで、エージェントには SQL そのものではなくツールとして見せます(詳しくは 2 章)。
1.1. 今回のゴール
| # | 確認したいこと | OK の条件 |
|---|---|---|
| 1 | 手元の MCP Toolbox から Aurora PostgreSQL に pgwire 接続できる | 起動ログでソースの接続に成功し、/api/toolset が定義したツールを返す |
| 2 | 自分で定義した postgres-sql ツールが API 経由で psql 直実行と同じ結果を返す | invoke の結果が psql 直実行と一致する |
| 3 | プリビルトの postgres ツール群が Aurora のメタデータを返す |
list_tables や database_overview が Aurora の実データを返す |
1.2. 結論(先出し)
- MCP Toolbox の postgres ソースは DB ユーザー名/パスワードだけで接続する。IAM 認証や Data API のような AWS 固有の接続経路は持たない。Aurora の IAM 認証を使いたいなら awslabs 側になる
- ツールの出し方は 2 通りある。自分で SQL を書いてツール化する
postgres-sqlと、--prebuilt postgresで一括で用意される DBA 向けツール群(本記事の v1.6.0 実機では 29 個) - 設定ファイルの書式が v1.6.0 で変わっていた。旧来の
sources:/tools:マップ形式ではなく、kind:と---で区切る新形式(flat format)になっている - つまずいた点が 2 つ。YAML のコメントに書いた
${ENV}が変数展開されて起動失敗したこと、そして プリビルト起動のパース失敗時に、展開後の設定(パスワード込み)がエラーに出たこと
2. MCP Toolbox の postgres ソースの要点
Toolbox そのものの立ち位置(DB の前に 1 枚かませてツール化するサーバ、複数 DB を同じ枠組みで並べられる点など)は前回の Oracle 版に書いたので、ここでは Aurora(PostgreSQL)に向けたときの違い だけに絞ります。
2.1. 接続は user/password のみ
postgres ソースの設定項目は host / port / database / user / password と、補助的な queryParams / queryExecMode / sqlCommenter です(公式: PostgreSQL source)。IAM 認証に相当するフィールドはありません。これは Oracle ソースが user/password 必須で OAuth を持たなかったのと同じ形です。
Aurora には IAM データベース認証や RDS Data API といった AWS 固有の接続経路がありますが、Toolbox の汎用的な postgres ソースはそれらを使いません。ふつうの PostgreSQL としてワイヤプロトコル(pgwire)で user/password 接続します。逆に言うと、どの PostgreSQL でも同じ設定で繋げる汎用性 と引き換えに、Aurora ならではの認証経路は使えない、という切り分けになります(この対比は 7 章)。
2.2. ツールの出し方が 2 通り
Toolbox で postgres のツールを用意する方法は 2 つあります。
-
自分で SQL を書く(
postgres-sql):tools.yamlに「この SQL をこの名前のツールにする」と定義する。SQL は Toolbox 側に閉じ込め、エージェントにはバインド変数($1,$2)だけ渡させる -
プリビルトを使う(
--prebuilt postgres): 設定ファイルなしで、DBA 向けの定番ツールが一括で用意される。list_tables/list_active_queries/get_query_plan/execute_sqlなどが含まれる
前者は「業務用途の SQL を承認済みツールとして絞って出す」向き、後者は「DB の状態をひととおり見る」向きです。本記事では両方を動かします。
3. 検証環境
| 項目 | 内容 |
|---|---|
| マシン | Windows 11 Pro + WSL2(Ubuntu) |
| MCP Toolbox | v1.6.0(linux/amd64、純 Go) |
| DB | Aurora PostgreSQL 17.9(Serverless v2、データベース名 appdb) |
| クライアント | psql 16.14(WSL、突き合わせ用) |
| 接続 | pgwire(5432 番、user/password、TLS 必須) |
バージョンは v1.6.0 時点のものです。MCP Toolbox は更新が速く、設定書式やプリビルトツールの構成が将来変わる可能性があります。実際、後述のとおり設定書式は v1.4.0 から変わっていました。再現する際は最新版ドキュメントとの差分に注意してください。
4. 準備
4.1. Aurora PostgreSQL を作る
検証用に Aurora PostgreSQL(Serverless v2)を新規に作成しました。手元の WSL から pgwire で届くように、次の 2 点を用意します。
-
パブリックアクセスを有効にしたインスタンス(
--publicly-accessible) - 専用のセキュリティグループで、自分のグローバル IP から 5432 番だけ許可する
マスターパスワードは自分で管理せず、RDS 管理(--manage-master-user-password)にしました。パスワードは AWS Secrets Manager に入り、こちらは Secret の ARN だけを扱います。
Serverless v2 は最小容量を 0 ACU にでき、アイドル時はゼロにスケールして課金がほぼ止まるので、「作って触って壊す」検証と相性が良いです。検証後はクラスタとインスタンスを削除しました。
4.2. Toolbox バイナリの入手(SHA256 照合)
リリースページ から v1.6.0 の linux/amd64 バイナリを取得し、リリースに載っている SHA256 と照合します。
curl -fsSL -o toolbox \
https://storage.googleapis.com/mcp-toolbox-for-databases/v1.6.0/linux/amd64/toolbox
chmod +x toolbox
echo "0cd6fa1773926a37e55c803542f16ef621eaea38b015ec9778dfaae9f30da302 toolbox" | sha256sum -c -
# => toolbox: OK
./toolbox --version
# => toolbox version 1.6.0+binary.linux.amd64...
4.3. 接続情報を環境変数にする
パスワードを設定ファイルやログに残さないため、起動時に Secrets Manager から取り出して環境変数に入れます。tools.yaml 側は ${ENV} 参照のままにします。
# Secrets Manager からマスター資格情報を取得し、環境変数へ(値は表示しない)
S=$(aws secretsmanager get-secret-value --secret-id "$SECRET_ARN" \
--query SecretString --output text)
export POSTGRES_HOST='<cluster-writer-endpoint>' # describe-db-clusters で取得
export POSTGRES_DATABASE='appdb'
export POSTGRES_USER=$(echo "$S" | jq -r .username)
export POSTGRES_PASSWORD=$(echo "$S" | jq -r .password)
5. 動かす(1)自分で定義した postgres-sql
5.1. tools.yaml(flat format)
v1.6.0 の設定書式は、kind: source / kind: tool / kind: toolset を --- で区切る形(flat format)です。旧来の sources: / tools: マップ形式とは違い、toolbox --help にも旧形式からの移行コマンド(toolbox migrate)があります。
題材は小さな EC の注文データ(customers / products / orders)にして、「顧客の注文を新しい順に返す」ツールなどを定義しました。SQL は Toolbox 側に置き、エージェントにはバインド変数だけ渡させます。
kind: source
name: aurora-pg
type: postgres
host: ${POSTGRES_HOST}
port: "5432"
database: ${POSTGRES_DATABASE}
user: ${POSTGRES_USER}
password: ${POSTGRES_PASSWORD}
queryParams:
sslmode: require
---
kind: tool
name: search_orders_by_customer
type: postgres-sql
source: aurora-pg
description: 指定した顧客の注文を新しい順に返す。
parameters:
- name: customer_id
type: string
description: 顧客ID(例 C001)
- name: top_n
type: integer
description: 取得する件数
statement: |
SELECT o.order_id, o.ordered_at, p.name AS product, o.qty, o.amount
FROM orders o JOIN products p ON p.product_id = o.product_id
WHERE o.customer_id = $1
ORDER BY o.ordered_at DESC
LIMIT $2;
---
kind: toolset
name: aurora
tools:
- search_orders_by_customer
- product_sales_summary
Aurora はデフォルトで TLS 必須(rds.force_ssl)なので、ソースの queryParams に sslmode: require を マップとして 与えています。この書き方は後述のプリビルト側(6 章)と扱いが違います。
host / user / password は tools.yaml に直書きせず ${ENV} 参照にします。値はシェル側の環境変数で与え、パスワードは Secrets Manager から実行時に取り込みます。
5.2. 起動と toolset
./toolbox --config tools.yaml --enable-api --address 127.0.0.1 --port 5000
起動ログ(抜粋)です。ソースの初期化に成功し、ツールが登録されています。
INFO "Starting MCP Toolbox for Databases version 1.6.0+binary.linux.amd64..."
INFO "Initialized 1 sources: aurora-pg"
INFO "Initialized 2 tools: search_orders_by_customer, product_sales_summary"
INFO "Initialized 2 toolsets: aurora, default"
INFO "Server ready to serve!"
Initialized 1 sources: aurora-pg と Server ready to serve! が出れば、Aurora への pgwire 接続ができています(ゴール 1 達成)。
5.3. invoke して psql 直実行と突き合わせ
/api/tool/<name>/invoke に JSON でパラメータを渡します。
curl -s -X POST http://127.0.0.1:5000/api/tool/search_orders_by_customer/invoke \
-H 'Content-Type: application/json' \
-d '{"customer_id":"C001","top_n":5}'
返ってきた結果を表にしたものです(顧客 C001 の注文は 3 件なので、top_n:5 でも 3 件返ります)。
search_orders_by_customer({"customer_id":"C001","top_n":5}・注文日の新しい順)
| order_id | ordered_at | product | qty | amount |
|---|---|---|---|---|
| O5006 | 2026-07-04 08:58 | 27インチモニター | 1 | 34800 |
| O5002 | 2026-07-01 09:03 | ノートPCスタンド | 2 | 8400 |
| O5001 | 2026-06-30 10:12 | メカニカルキーボード | 1 | 12800 |
同じ条件を psql で直接実行した結果も、同じ 3 件・同じ並び・同じ金額でした。もう 1 本の集計ツールも一致します。
product_sales_summary(商品別の売上合計・多い順)
| product_id | name | total_qty | total_amount |
|---|---|---|---|
| P200 | 27インチモニター | 2 | 69600 |
| P100 | メカニカルキーボード | 3 | 38400 |
| P300 | USB-C ドッキングステーション | 1 | 18800 |
| P400 | ノートPCスタンド | 2 | 8400 |
Toolbox 経由でも psql 直実行でも、投入データと一致する結果が返りました(ゴール 2 達成)。接続とバインド変数が想定どおり動いている、ということです。なお invoke 結果の ordered_at は JST(+09:00)、psql 直実行はサーバのデフォルト表示で UTC でしたが、これは表示タイムゾーンの違いだけで、指している時刻は同じです。
6. 動かす(2)プリビルトの postgres(29 ツール)
設定ファイルを書かずに、DBA 向けのツールを一括で出すこともできます。プリビルトは環境変数(POSTGRES_HOST / POSTGRES_PORT / POSTGRES_DATABASE / POSTGRES_USER / POSTGRES_PASSWORD)で接続先を渡します。
./toolbox --prebuilt postgres --enable-api --address 127.0.0.1 --port 5001
/api/toolset を見ると、本記事の v1.6.0 実機では 29 個 のツールが登録されていました(公式のプリビルト説明では「33 tools, including…」とあり数が違うので、実機で数えるのが確実です)。中身は database_overview / execute_sql / get_query_plan / list_active_queries / list_tables / list_indexes / list_locks / long_running_transactions など、DBA が DB の状態を調べるためのツールが揃っています。
代表的なツールを invoke した結果です。
list_tables(抜粋): public スキーマの 3 テーブル(customers / orders / products)について、列・主キー・外部キー・インデックスが返りました。たとえば orders には customers と products への外部キーが定義されている、といった構造がそのまま取れます。
database_overview
| 項目 | 値 |
|---|---|
| pg_version | 17.9 |
| is_replica | false |
| max_connections | 411 |
| current_connections | 15 |
| active_connections | 1 |
execute_sql({"sql":"SELECT count(*) AS orders FROM orders"})
[{"orders":6}]
list_installed_extensions: plpgsql(PL/pgSQL 手続き言語)が返りました。
いずれも Aurora の実データを返しており、プリビルトの DBA ツール群が Aurora でそのまま動くことを確認できました(ゴール 3 達成)。
プリビルトは接続ユーザーの権限で動きます。pg_stat_* を読むツール(list_active_queries など)で結果が空になる場合は、接続ユーザーに pg_monitor を付与すると見えるようになります。今回はマスターユーザーで接続したため、そのまま参照できました。
7. 考察
7.1. awslabs postgres-mcp-server との違い
同じ Aurora を、直前に検証した awslabs postgres-mcp-server(AWS 公式の awslabs/mcp にある PostgreSQL 向け MCP サーバ)と並べると、設計思想の違いがはっきりします。
| 観点 | Google MCP Toolbox v1.6.0(postgres) | awslabs postgres-mcp-server v1.1.7 |
|---|---|---|
| 接続方式 | pgwire(user/password)のみ | Data API/pgwire 直接接続/IAM 認証トークン/RDS 管理シークレット |
| ツールの出し方 | 自作 postgres-sql(SQL を定義)+ プリビルト 29 個(DBA 系) | 汎用 run_query 1 本+スキーマ/接続系(計 7 個) |
| readonly の絞り方 | tools.yaml で SQL を固定=設計で絞る/プリビルトの execute_sql は任意 SQL |
--allow_write_query 無指定で run_query の SQL キーワード検査 |
| クラウド依存 | 汎用 postgres なのでどの PostgreSQL でも同じ設定 | RDS/Aurora 専用(AWS の API 前提) |
ざっくり言うと、awslabs 側は Aurora(RDS)に特化して、Data API や IAM 認証といった AWS の接続経路まで扱えるのに対し、Toolbox 側は どの PostgreSQL でも同じように繋げる汎用性を持つ代わりに、接続は user/password に限られます。Aurora の IAM 認証を MCP から使いたい、という要件なら awslabs 側が向いています。
ツールの考え方も対照的です。Toolbox は「自分で SQL をツール化して承認済みのものだけ叩かせる」か「プリビルトで DBA ツールをまとめて出す」の 2 択で、awslabs は「汎用の run_query に SQL を書かせ、キーワード検査で書き込みを止める」形です。どちらも一長一短で、用途(決まった業務クエリを出したいのか、自由に触りたいのか)で選ぶことになります。
7.2. つまずいた点(1)コメントの ${ENV} が展開される
最初の起動で、次のエラーが出て落ちました。
error parsing environment variables: environment variable not found: "ENV" (line 3, column 14)
【原因】 tools.yaml の 3 行目に、説明のつもりでコメントに ${ENV} と書いていました。Toolbox は設定ファイルをコメントごと走査して環境変数参照を展開するため、コメント内の ${ENV} も「ENV という環境変数を使う」と解釈され、見つからずに落ちていました。
【対処法】 コメントにドル記号+波括弧のリテラルを書かないようにします。秘匿値を環境変数化する説明は、記号を使わず文章で書けば問題ありません。
7.3. つまずいた点(2)プリビルトのパース失敗で設定が丸見えになる
プリビルトの postgres に、TLS を有効にしようとして環境変数 POSTGRES_QUERY_PARAMS='sslmode=require' を渡したところ、パースに失敗しました。プリビルトは起動時に、渡された環境変数から設定 YAML を内部で組み立てます。このとき POSTGRES_QUERY_PARAMS の値は queryParams フィールドにそのまま入りますが、sslmode=require という文字列が queryParams: sslmode=require というスカラー値として埋め込まれ、queryParams はマップ(key: value)を期待するため型が合わずエラーになりました(この「展開後の YAML」はエラーメッセージにそのまま出ていました)。
問題はエラーの出方でした。展開後の設定ドキュメントが、パスワードの平文を含んだままエラーメッセージに出力されたのです(下は該当箇所をマスクしたもの)。
unable to parse prebuilt tool configuration for 'postgres': ...
3 | name: postgresql-source
4 | password: **** # ← 展開後のパスワードがそのまま出る
5 | port: 5432
> 6 | queryParams: sslmode=require
^ string was used where mapping is expected
【対処法】 そもそもプリビルトに SSL 用の生パラメータを渡す必要はありませんでした。Aurora は rds.force_ssl がデフォルトで有効ですが、POSTGRES_QUERY_PARAMS を指定しなくても TLS で接続できました(Toolbox が内部で使う pgx ドライバはデフォルトで SSL を優先して接続するためと考えられます)。自作ソース側で SSL を指定したいときは、5.1 のように queryParams を マップ(sslmode: require)で書きます。
あわせて運用上の教訓として、秘匿値を環境変数で渡す起動では、パース失敗時に展開後の設定が出力され得る点は意識しておくとよいです。共有端末や残るログに秘匿値を出さないよう、失敗時のログは扱いに注意します。この「秘匿値がどこに露出し得るか」という視点は、awslabs 側で見た「readonly はあくまで SQL 層の歯止めで、本体は IAM」という整理と同じく、MCP サーバを本番で使う前に確認しておきたい観点です。
8. まとめ
Google の MCP Toolbox for Databases から Aurora PostgreSQL に pgwire 接続し、自作の postgres-sql ツールとプリビルトの DBA ツール群が、どちらも Aurora の実データを返すところまで確認できました。
| ポイント | 結論 |
|---|---|
| 接続方式 | postgres ソースは user/password のみ。IAM 認証/Data API は持たない(使いたいなら awslabs 側) |
| ツールの出し方 | 自作 postgres-sql(SQL を定義)/--prebuilt postgres(v1.6.0 実機で 29 個の DBA ツール) |
| 設定書式 | v1.6.0 は kind: + --- の flat format。旧マップ形式から移行コマンドあり |
| SSL | 自作ソースは queryParams をマップで sslmode: require。プリビルトは無指定でも pgx のデフォルトで TLS 接続される |
| つまずき | コメント内 ${ENV} の展開/プリビルトのパース失敗時に設定(パスワード込み)が出力される |
汎用の postgres ソースなので、Aurora に限らず他の PostgreSQL でも同じ設定で繋げます。一方で Aurora ならではの接続経路(IAM 認証・Data API)は Toolbox では扱えないため、そこは AWS 公式の awslabs postgres-mcp-server と使い分けることになります。同じ Aurora を 2 つの MCP サーバから触ってみると、「汎用で複数 DB を同じ枠組みに載せる」Toolbox と「Aurora に特化して AWS の接続経路まで扱う」awslabs という、狙いの違いがよく見えました。
なお MCP クライアントは複数の MCP サーバを同時に登録できるので、MCP サーバを 1 つに統一する必要はありません。1 つのクライアントから「Aurora は awslabs、Cloud SQL や BigQuery は Toolbox」のようにターゲットごとに使い分けられますし、逆に、そのクラウド固有の機能が要らなければ Toolbox 1 本に汎用 postgres ソースとして Aurora も並べる手もあります。どちらを選ぶかは、各クラウド固有の機能を取るか、運用するサーバやツール定義を 1 つに揃える(同じ tools.yaml を他の PostgreSQL にも流用できる可搬性も含む)を取るか のトレードオフです。クラウド固有の機能が要るならターゲットごとに使い分け、運用や定義をそろえたいなら Toolbox に寄せる、という選び方になります。ただし Toolbox に寄せても揃うのはツール定義と設定ファイルの書式までで、資格情報の取得元(今回の AWS Secrets Manager など)といったクラウド固有の運用は、${ENV} の外側に残ります。