1. はじめに
これまで OCI Database Tools MCP Server1 や SQLcl MCP2、Google の MCP Toolbox for Databases3 と、「MCP サーバ経由で LLM クライアントから DB につなぐ」検証を続けてきました。今回はその AWS 版として、awslabs/mcp リポジトリにある Amazon Aurora Postgres MCP Server(awslabs.postgres-mcp-server)4 を Claude Desktop につなぎ、Aurora PostgreSQL(Serverless v2)に SQL を実行できるところまでを確かめます。今回検証したバージョンは 1.1.75 です。
着手前は「このサーバは RDS Data API6 経由らしい。だとすると Data API を有効化した Aurora が前提で、通常の RDS for PostgreSQL にはつなげないのでは」と想定していました。ところが公式 README の "Connection Methods" を読むと、接続方式は Data API 限定ではなく 3 つあります4。
| 方式 | 説明(README の対応表より) | 対応 DB |
|---|---|---|
pgwire |
PostgreSQL ワイヤプロトコルでの直接接続 | Aurora PostgreSQL / RDS for PostgreSQL |
pgwire_iam |
pgwire と同じ経路で、認証に IAM を使う |
Aurora PostgreSQL のみ |
rdsapi |
RDS Data API 経由で接続 | Aurora PostgreSQL のみ |
そこで本記事は「つないでみた」に加えて、同一の Aurora クラスタに rdsapi と pgwire の両方で接続し、前提条件の違いを実機で確かめることを軸にします。あわせて、デフォルトの読み取り専用(readonly)構成で書き込みが本当に拒否されるかも確認します。
1.1. 今回の検証ゴール
| # | 検証項目 | 達成できたとみなす条件 |
|---|---|---|
| 1 | Claude Desktop から Aurora PostgreSQL(Serverless v2)に接続できる | サンプルスキーマへの SELECT の結果が、投入データと一致する形で会話に返る |
| 2 | 接続 2 方式(rdsapi / pgwire)を同一クラスタで比較できる | 両方式で SELECT が返り、Data API 無効時に rdsapi だけが使えなくなることを確認できる |
| 3 | 読み取り専用の構成で書き込みを防げる | 書き込みを指示した際に実行が拒否され、DB 側に変更が入っていない |
1.2. 結論(先出し)
- 接続方式は RDS Data API 限定ではなく 3 方式。同一の Aurora クラスタに rdsapi・pgwire の両方で接続し、SELECT や JOIN 集計が投入データ・手計算と一致する結果を返した
- 方式の切り替えは会話中に
connect_to_databaseツールで行え、MCP サーバの再起動は不要だった - rdsapi は「クラスタ側で Data API を有効化済み」が前提。無効化すると MCP サーバは起動時の疎通検証で終了してしまう(
HttpEndpointNotEnabledException) - デフォルト(
--allow_write_queryなし)では INSERT(DML)も DROP(DDL)も拒否され、前後のスナップショット比較で DB が無変更であることを確認した - ただしこの読み取り専用が対象にするのは
run_queryの SQL だけで、create_clusterのような AWS API を呼ぶツールは対象外だった(1.1.7 のソースコードで確認) - README の設定例と 1.1.7 の実引数は食い違っており、セットアップは
--helpの出力をもとに作る必要があった
2. 検証環境
| 項目 | 内容 |
|---|---|
| MCP クライアント | Claude Desktop(Windows 版) |
| MCP サーバ |
awslabs.postgres-mcp-server 1.1.75(WSL2 上の uvx で実行) |
| Aurora PostgreSQL | 17.9 / Serverless v2(0〜2 ACU・ゼロスケール)/ 東京リージョン |
| クラスタ |
pgmcp-cluster(Data API 有効・マスターパスワードは RDS 管理)/ インスタンス pgmcp-instance-1(db.serverless・パブリックアクセス可) |
| サンプル DB |
appdb(products 8 行 / orders 10 行 / order_items 19 行) |
クラスタ構成(0〜2 ACU・300 秒で自動停止のゼロスケール)は、以前ゼロスケールの再開時間を計測したときの構成の流用です7。検証中しか動かさないのでコストを抑えられます。
3. 構成と準備
3.1. 全体構成
Claude Desktop(Windows)から stdio で WSL2 上の MCP サーバを起動し、そこから Aurora へ 2 経路でつなぎます。
本記事では接続方式を公式 README の呼び名(rdsapi / pgwire / pgwire_iam)で書きます。起動引数やツール引数に渡す値は RDS_API / PG_WIRE_PROTOCOL / PG_WIRE_IAM_PROTOCOL です。
3.2. Aurora PostgreSQL Serverless v2 の作成
Aurora クラスタは次の方針で作りました。
-
--enable-http-endpoint: rdsapi 用に RDS Data API を有効化する。Serverless v2 でも Data API が使えることは公式のリージョン表で確認できます(東京は Aurora PostgreSQL 13.11 以降など)8 -
--manage-master-user-password: マスターパスワードを RDS が Secrets Manager に自動生成・管理する。postgres-mcp-server は--secret_arnを省略すると「クラスタの MasterUserSecret」に自動でフォールバックするため(--helpに記載)、シークレットの手動作成が要らなくなります - セキュリティグループ: pgwire の直接接続用に、TCP 5432 のインバウンドを検証マシンのグローバル IP /32 だけに許可。インスタンスはパブリックアクセス可で作成
# クラスタ(Serverless v2・ゼロスケール・Data API 有効・マスターパスワードは RDS 管理)
aws rds create-db-cluster \
--db-cluster-identifier pgmcp-cluster \
--engine aurora-postgresql \
--engine-version 17.9 \
--master-username postgres \
--manage-master-user-password \
--database-name appdb \
--enable-http-endpoint \
--serverless-v2-scaling-configuration "MinCapacity=0,MaxCapacity=2,SecondsUntilAutoPause=300" \
--vpc-security-group-ids sg-xxxxxxxxxxxx \
--region ap-northeast-1
# インスタンス(db.serverless・パブリックアクセス可)
aws rds create-db-instance \
--db-instance-identifier pgmcp-instance-1 \
--db-cluster-identifier pgmcp-cluster \
--db-instance-class db.serverless \
--engine aurora-postgresql \
--publicly-accessible \
--region ap-northeast-1
# pgwire 用: 5432 を検証マシンの IP だけに許可
aws ec2 authorize-security-group-ingress \
--group-id sg-xxxxxxxxxxxx \
--protocol tcp --port 5432 \
--cidr <検証マシンのグローバル IP>/32
作成から約 7 分でインスタンスが available になりました。
3.3. サンプルスキーマの投入 — Data API だけで完結
自然言語からの JOIN・集計が試せるように、小さな書店の商品・注文データを appdb に投入します。
CREATE TABLE products (
product_id integer PRIMARY KEY,
name text NOT NULL,
category text NOT NULL,
price_yen integer NOT NULL
);
CREATE TABLE orders (
order_id integer PRIMARY KEY,
ordered_at timestamp NOT NULL,
customer_name text NOT NULL
);
CREATE TABLE order_items (
order_id integer NOT NULL REFERENCES orders (order_id),
product_id integer NOT NULL REFERENCES products (product_id),
quantity integer NOT NULL,
PRIMARY KEY (order_id, product_id)
);
INSERT INTO products (product_id, name, category, price_yen) VALUES
(1, 'PostgreSQL 実践入門', '書籍', 3200),
(2, 'Aurora 設計パターン', '書籍', 3800),
(3, 'MCP プロトコル解説', '書籍', 2800),
(4, 'SQL チューニング事典', '書籍', 4500),
(5, 'ノート PC スタンド', '雑貨', 2400),
(6, 'キーボードクリーナー', '雑貨', 800),
(7, 'データベースステッカー', '雑貨', 500),
(8, 'クラウド認定問題集', '書籍', 3000);
INSERT INTO orders (order_id, ordered_at, customer_name) VALUES
(101, '2026-06-01 10:15:00', '佐藤'),
(102, '2026-06-03 14:30:00', '鈴木'),
(103, '2026-06-05 09:45:00', '高橋'),
(104, '2026-06-08 16:20:00', '田中'),
(105, '2026-06-10 11:05:00', '伊藤'),
(106, '2026-06-14 13:50:00', '渡辺'),
(107, '2026-06-18 18:10:00', '山本'),
(108, '2026-06-21 10:40:00', '中村'),
(109, '2026-06-25 15:25:00', '小林'),
(110, '2026-06-28 12:00:00', '加藤');
INSERT INTO order_items (order_id, product_id, quantity) VALUES
(101, 1, 1), (101, 7, 2),
(102, 2, 1), (102, 4, 1),
(103, 3, 2),
(104, 1, 1), (104, 5, 1),
(105, 8, 1),
(106, 4, 1), (106, 6, 3),
(107, 2, 2), (107, 3, 1),
(108, 1, 1), (108, 8, 1), (108, 7, 1),
(109, 5, 2),
(110, 3, 1), (110, 4, 1), (110, 6, 1);
投入は psql ではなく Data API(aws rds-data execute-statement)で行いました。SG の 5432 開放を待たなくても DDL・INSERT が通るので、先にデータを入れられます。ただし Data API は 1 コールにつき 1 ステートメント(複文不可)なので、上の SQL を 1 文ずつ実行しました。
# 行数の確認(投入後の検証)
aws rds-data execute-statement \
--resource-arn arn:aws:rds:ap-northeast-1:xxxxxxxxxxxx:cluster:pgmcp-cluster \
--secret-arn "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:rds!cluster-xxxxxxxx" \
--database appdb \
--sql "SELECT (SELECT count(*) FROM products), (SELECT count(*) FROM orders), (SELECT count(*) FROM order_items)"
行数は products = 8、orders = 10、order_items = 19 で投入どおりです。pgwire 側の疎通も WSL2 の psql からライターエンドポイントに SSL 接続し、PostgreSQL 17.9 on aarch64 が返ることを確認しました。
3.4. 起動引数は --help で確定する — README の設定例と食い違う
最初のつまずきです。公式サイト / README の設定例には --connection-string postgresql://... を渡す形が載っていますが、1.1.7 の --help にそのオプションは存在しません。実際の引数体系は次のとおりです。
usage: awslabs.postgres-mcp-server [-h]
[--connection_method CONNECTION_METHOD]
[--db_cluster_arn DB_CLUSTER_ARN]
[--db_type DB_TYPE]
[--db_endpoint DB_ENDPOINT]
[--region REGION] [--allow_write_query]
[--database DATABASE] [--port PORT]
[--secret_arn SECRET_ARN]
options:
--connection_method CONNECTION_METHOD
Connection method to the database. It can be RDS_API,
PG_WIRE_PROTOCOL OR PG_WIRE_IAM_PROTOCOL)
--db_cluster_arn DB_CLUSTER_ARN
ARN of the RDS or Aurora Postgres cluster
--db_type DB_TYPE APG for Aurora Postgres or RPG for RDS Postgres
--db_endpoint DB_ENDPOINT
Instance endpoint address
--region REGION AWS region
--allow_write_query Enforce readonly SQL statements
--database DATABASE Database name
--port PORT Database port (default: 5432)
--secret_arn SECRET_ARN
Optional Secrets Manager ARN override. ...(中略)...
2025 年時点の AWS Blog の設定例(--resource_arn / --secret_arn を渡す Data API 前提の形)9とも異なるので、Web 上のセットアップ記事を参照するときはバージョンに注意が必要です。設定はドキュメントの例を写すのではなく、使うバージョンの --help の出力を確認して作るのが確実でした。
細かい点ですが、--allow_write_query のヘルプ文は "Enforce readonly SQL statements" となっていて紛らわしいです。実際の挙動は「無指定 = 読み取り専用、付けると書き込みを許可」で(README の記述とも整合します)、6 章の実測でも無指定で書き込みが拒否されました。
3.5. Claude Desktop への登録 — --db_endpoint は省略すると起動に失敗する
claude_desktop_config.json に次を追記します(アカウント ID とエンドポイントの固有部は xxxx でマスクしています。AWS_PROFILE はご自身のプロファイル名に読み替えてください)。
{
"mcpServers": {
"awslabs.postgres-mcp-server": {
"command": "wsl.exe",
"args": [
"bash",
"-lc",
"AWS_PROFILE=aws-verify uvx awslabs.postgres-mcp-server@1.1.7 --connection_method RDS_API --db_cluster_arn arn:aws:rds:ap-northeast-1:xxxxxxxxxxxx:cluster:pgmcp-cluster --db_type APG --db_endpoint pgmcp-cluster.cluster-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com --database appdb --region ap-northeast-1"
]
}
}
}
なお AWS_PROFILE で指定するプロファイルは、Windows 側ではなく WSL 側の ~/.aws/credentials(~/.aws/config)に定義したものを参照します。MCP サーバの実行環境は WSL なので、認証情報も WSL 側に用意しておいてください。
ここで 2 つ目のつまずきがありました。1.1.7 は --db_endpoint を省略すると、rdsapi(RDS_API)構成でも起動に失敗します("No database connection available" で終了)。原因は接続情報の検索キーの不一致です。サーバ内部では、接続の登録キーに AWS から解決したライターエンドポイントが入ります。一方、起動時の疎通検証(SELECT 1)は CLI 引数の db_endpoint(未指定なら None)をそのままキーにして接続を探すため、未指定だと登録済みの接続が見つかりません(1.1.7 のソースで確認10)。
対処は上の設定のように --db_endpoint にクラスタのライターエンドポイントを指定することです。エンドポイントの文字列は、aws rds describe-db-clusters で取得した値をそのまま使ってください。なお、指定した値はクラスタの正規エンドポイント一覧(writer / reader / カスタム / メンバー)と突き合わされ、一致しないと接続を拒否する検査も入っています(認証情報を第三者のホストに向けさせない対策、とソースコメントに記載があります)。別解として、起動時は接続指定なしで立ち上げておき、会話の中で connect_to_database ツールから接続する方法もあります。
エンドポイントを指定した状態では、起動ログに "Successfully validated database connection to Postgres" が出て正常に起動しました。
4. つないで聞いてみる(ゴール 1)
4.1. ツール一覧 — SQL 実行だけでなくクラスタ作成まである
Claude Desktop を再起動し、まずツール一覧を聞いてみます。
postgres-mcp-server で使えるツールを一覧してください
返ってきたのは次の 7 ツールです(事前に stdio の JSON-RPC で取得した tools/list とも一致)。
| ツール名 | 用途 |
|---|---|
run_query |
PostgreSQL に対して SQL を実行 |
get_table_schema |
指定テーブルのカラム定義・コメントを取得 |
connect_to_database |
指定した DB に接続し、接続情報を内部保存 |
is_database_connected |
接続済みかどうかを確認 |
get_database_connection_info |
保存済みの接続情報を全件取得 |
create_cluster |
Aurora PostgreSQL クラスタを新規作成 |
get_job_status |
バックグラウンドジョブ(クラスタ作成など非同期処理)の状態を確認 |
SQL 実行系(run_query / get_table_schema)だけでなく、クラスタ作成という AWS API 側の操作(create_cluster / get_job_status)を持つのが特徴です。これまで触った OCI Database Tools MCP や SQLcl MCP は SQL 実行が中心だったので、この点は後で 6.4 章・7.3 章で掘り下げます。
Claude Desktop 側では、MCP サーバのツールごとに使用可否・承認要否を設定できます。今回はすべて「承認が必要」のまま進めました。
4.2. 自然言語で SELECT
サンプルデータについて聞いてみます。
appdb の products テーブルにどんな商品があるか教えて
会話の流れは次のようになりました。
- 「appdb の接続情報を確認してから products テーブルを見てみます」と、まず
get_database_connection_infoで接続情報を確認 - スキーマ確認と SELECT を実行するも、一度失敗
- 「
connection_methodが必須のようなので、接続情報にあったrdsapiを指定して再実行します」と自己修正して成功
返ってきた表がこちらです。
| product_id | name | category | price_yen |
|---|---|---|---|
| 1 | PostgreSQL 実践入門 | 書籍 | 3,200 |
| 2 | Aurora 設計パターン | 書籍 | 3,800 |
| 3 | MCP プロトコル解説 | 書籍 | 2,800 |
| 4 | SQL チューニング事典 | 書籍 | 4,500 |
| 5 | ノート PC スタンド | 雑貨 | 2,400 |
| 6 | キーボードクリーナー | 雑貨 | 800 |
| 7 | データベースステッカー | 雑貨 | 500 |
| 8 | クラウド認定問題集 | 書籍 | 3,000 |
3.3 章で投入した 8 行と完全一致しており、ゴール 1 は達成です。途中で run_query 系ツールの必須引数 connection_method を LLM が一度省略して失敗し、保存済みの接続情報から rdsapi を読み取って自己修正する場面がありました(7.4 章で触れます)。
5. 接続方式を比べる(ゴール 2)
5.1. 会話の中で pgwire に切り替えて JOIN 集計
MCP サーバは rdsapi(RDS_API)構成で起動したままです。この状態で、会話から pgwire の接続を追加してみます。
東京リージョンの Aurora クラスタ pgmcp-cluster の appdb に、接続方式 pgwire で接続してください。接続できたら「6 月の注文で売上金額が多い商品トップ 3」を教えてください
- クラスタのライターエンドポイントを AWS CLI で取得し、
connect_to_databaseをPG_WIRE_PROTOCOL方式で実行 → 「接続に成功しました」 -
run_queryの 1 回目はカラム名の想定違い(id/unit_priceを想定、実際はorder_id/price_yen)で失敗。get_table_schemaで実スキーマを確認してから再実行 - 3 テーブルの JOIN 集計の結果が返る
| 順位 | 商品名 | 売上金額 |
|---|---|---|
| 1 | SQL チューニング事典 | 13,500円 |
| 2 | Aurora 設計パターン | 11,400円 |
| 3 | MCP プロトコル解説 | 11,200円 |
投入データからの手計算と突き合わせると、次のとおり一致します。
- SQL チューニング事典(4,500 円 × 3 冊)= 13,500 円
- Aurora 設計パターン(3,800 円 × 3 冊)= 11,400 円
- MCP プロトコル解説(2,800 円 × 4 冊)= 11,200 円
- 次点の PostgreSQL 実践入門は 9,600 円でトップ 3 圏外
ポイントは MCP サーバを再起動していないことです。rdsapi で起動したサーバのまま、会話の中で pgwire の接続を追加できました。接続情報はサーバ内に保存され、get_database_connection_info で一覧できます。
5.2. Data API を無効化すると rdsapi はどうなるか
次に、rdsapi の前提条件「クラスタ側で Data API 有効化」を崩してみます。
aws rds disable-http-endpoint \
--resource-arn arn:aws:rds:ap-northeast-1:xxxxxxxxxxxx:cluster:pgmcp-cluster
この状態で CLI の rds-data を実行すると、次のエラーになります。
An error occurred (HttpEndpointNotEnabledException) when calling the ExecuteStatement operation:
HttpEndpoint is being disabled for resource arn:aws:rds:ap-northeast-1:************:cluster:pgmcp-cluster.
(無効化直後は "is being disabled"、反映が終わると "is not enabled" にメッセージが変わります。API のレスポンス自体は即時に HttpEndpointEnabled: false を返しますが、実際の反映には数秒のラグがありました)
rdsapi 構成の MCP サーバをこの状態で起動すると、起動時の疎通検証(SELECT 1)で例外になり、サーバは起動せず終了します。
ERROR | awslabs.postgres_mcp_server.connection.rds_api_connection:_execute_readonly_query:143
- RDS Data API query failed, transaction rolled back
botocore.errorfactory.HttpEndpointNotEnabledException: An error occurred (HttpEndpointNotEnabledException)
when calling the BeginTransaction operation: HttpEndpoint is not enabled for resource
arn:aws:rds:ap-northeast-1:************:cluster:pgmcp-cluster.
ERROR | awslabs.postgres_mcp_server.server:main:1225
- Failed to validate database connection to Postgres. Exit the MCP server
クライアント側からは「MCP サーバが落ちている」ようにしか見えないので、この状態の原因はサーバログを見ないと分かりません。
すでに rdsapi の接続が保存されている稼働中のセッションで試すと、会話面まで前提条件の違いが伝わってきました。
接続方式 rdsapi で products テーブルの件数を数えてください(pgwire は使わないでください)
- 保存済みの rdsapi 接続で
run_queryを実行 → エラー - LLM が AWS CLI でクラスタ状態を自ら確認し、
HttpEndpointEnabledがFalseであることを特定 - 「Data API を再度有効化する必要があります」と対処を提示し、設定変更の実行可否を確認(→ 今回は「実行しない」を選択)
- 「rdsapi 接続方式では products の件数を取得できません(
HttpEndpointNotEnabledExceptionになります)。pgwire 接続で代わりに数えることもできますが、いかがですか?」と代替案を提示
rdsapi と pgwire の前提条件の違いが、そのまま会話の代替案として現れた形です。なお再有効化(enable-http-endpoint)はレスポンス即時に HttpEndpointEnabled: true を返すものの、クエリが通るまで約 2 分かかり、その間は "HttpEndpoint is being enabled" のエラーでした。反映中に enable を再発行すると InvalidResourceStateFault になる点も注意です。復旧後の SELECT count(*) FROM products は 8 で、無効化 → 再有効化によるデータへの影響はありませんでした。
5.3. 対応関係と前提条件のまとめ
今回の実測と公式の対応表4を突き合わせると次のようになります。
| 構成 | rdsapi | pgwire | pgwire_iam |
|---|---|---|---|
| Aurora PostgreSQL(Data API 有効) | ✅ 実測 OK | ✅ 実測 OK | 未検証(IAM 認証の有効化が別途必要) |
| Aurora PostgreSQL(Data API 無効) | ❌ 実測 NG(HttpEndpointNotEnabledException) |
✅ 実測 OK(Data API と無関係) | 未検証 |
| 非 Aurora の RDS for PostgreSQL | ❌ 非対応(公式) | ✅ 対応(公式。実機は省略) | ❌ 非対応(公式) |
実測した 2 方式の前提条件を並べるとこうなります。
| 観点 | rdsapi(RDS Data API) | pgwire(直接接続) |
|---|---|---|
| ネットワーク前提 | 不要(HTTPS エンドポイント。SG の 5432 開放なしで届く) | SG の 5432 許可+パブリックアクセス可(または VPC 内の到達性)が必要 |
| クラスタ側の前提 | Data API の有効化(--enable-http-endpoint) |
なし |
| 認証 | IAM(rds-data:ExecuteStatement)+ Secrets Manager |
Secrets Manager のパスワード(マスターまたは指定シークレット) |
| 対応 DB | Aurora のみ | Aurora & RDS for PostgreSQL |
| 会話中の切り替え |
connect_to_database で可能(再起動不要) |
同左 |
6. 読み取り専用で書き込みを頼んでみる(ゴール 3)
MCP サーバは --allow_write_query なし(= 1.1.7 のデフォルト、読み取り専用)で起動した状態です。
6.1. INSERT(DML)は拒否される
products テーブルに「試し書き」という商品を 1,000 円で追加してください
- LLM が接続先を確認し、接続確立とスキーマ確認まで進む
-
product_idが自動採番でないことを確認し、「現在の最大値は 8。9 として追加、category はどうするか」と確認してくる(→ NULL のままを選択) -
run_queryで INSERT を実行 → 「現在接続している MCP サーバは読み取り専用(readonly)モードで構成されているためブロックされました」
6.2. DROP TABLE(DDL)も拒否される
では products テーブルを DROP してください
- LLM が「不可逆な破壊的操作」と警告し、実行可否を確認してくる(→ 検証のためそのまま実行を選択)
-
run_queryで DROP を実行 → 「想定通り、readonly 設定により DROP も拒否されました」「products テーブルは無傷です」
DML(INSERT)だけでなく DDL(DROP)もブロックされることを確認できました。
6.3. DB 側が無変更であることの確認
会話上の「拒否されました」だけでは不十分なので、書き込み指示の前後で同一クエリのスナップショットを Data API で取得し、突き合わせました。
| 指標 | before | after | 判定 |
|---|---|---|---|
| products 行数 | 8 | 8 | 一致 |
| orders 行数 | 10 | 10 | 一致 |
| order_items 行数 | 19 | 19 | 一致 |
| products.price_yen 合計 | 21,000 | 21,000 | 一致 |
| order_items.quantity 合計 | 25 | 25 | 一致 |
| public スキーマのテーブル数 | 3 | 3 | 一致(DROP されていない) |
INSERT・DROP とも実行が拒否され、DB 側に一切の変更が入っていません。ゴール 3 も達成です。
6.4. この読み取り専用の実体 — SQL のキーワード検査で、create_cluster は対象外
この readonly の実体は、run_query に渡された SQL に対するキーワード・関数のブロックリスト検査です。README 自身が次のように明記しています4。
Treat this as a best-effort, defense-in-depth mechanism, not a security boundary.
— README "Security Consideration"
「ベストエフォートの多層防御であり、セキュリティ境界ではない」という位置づけで、README は最小権限の PostgreSQL ロールで接続することもあわせて推奨しています。
さらに 1.1.7 のソースを確認すると、readonly の検査があるのは run_query の SQL 検査だけで、create_cluster には readonly のチェックがありません。readonly 構成のままでも、create_cluster は AWS API でクラスタ作成を実行する実装です10(課金を避けるため実機では実行せず、ソースの確認にとどめています)。歯止めになるのは実行 IAM の権限と、4.1 章で見たクライアント側のツール単位の承認です。
7. 考察
7.1. 接続 3 方式の使い分け
README "Connection Methods" の対応表では、pgwire が Aurora と RDS for PostgreSQL の両対応、pgwire_iam と rdsapi は Aurora 専用です4。
前提条件の差は 5.3 章のとおりで、rdsapi は SG を開けずに HTTPS で届き、pgwire は 5432 への到達性(SG 許可とパブリックアクセス可、または VPC 内)を用意する必要がありました。
この 2 点から、使い分けは次のように整理できます。
- VPC の外の端末から SG を開けずにつなぎたい → rdsapi(クラスタ側で Data API の有効化が必要)
- 非 Aurora の RDS for PostgreSQL、または Data API を有効化できないクラスタ → pgwire(ネットワーク到達性の確保が必要)
- パスワードではなく IAM 認証に寄せたい → pgwire_iam(今回は未検証)
なお「MCP サーバがどの DB につなげるか」という観点では、以前 OCI Database Tools MCP が Oracle Database 接続限定であることを確かめました11が、こちらは pgwire で非 Aurora の RDS までカバーしており、PostgreSQL の範囲では適用先が広い設計です。
7.2. rdsapi は読み取りでもトランザクションを張る
Data API 無効時のエラーは ExecuteStatement ではなく BeginTransaction 呼び出しで発生しました。読み取り専用のクエリでも BeginTransaction → 実行 → Commit/Rollback という流れで Data API を呼ぶ実装で、ソースでも読み取り経路の関数(_execute_readonly_query)がロールバック付きで実装されています10。1 回の SELECT が複数回の API 呼び出しになることは、エラーの出どころを探すときに知っておくと迷わずに済みます。
7.3. 「読み取り専用」の境界は SQL だけ — 土台は IAM とツール承認
6.4 章のとおり、README は readonly を "best-effort, defense-in-depth mechanism, not a security boundary" と明記し、最小権限の PostgreSQL ロールの併用を推奨しています(README "Security Consideration"4)。
ツール一覧には SQL 実行系に加えて create_cluster / get_job_status という AWS API 側の操作が並びます。ソース確認のとおり create_cluster は readonly の検査対象外なので、--allow_write_query を外して守れる範囲は SQL のデータ操作だけです。クラスタ作成のような AWS リソース操作を止めるのは、readonly フラグではなく、(1) MCP サーバを動かす IAM プリンシパルの権限を最小にすること、(2) クライアント側でツール単位の承認を挟むこと、の 2 つです。
この構図は「MCP サーバに何を許可するか」を SQL 権限だけで考えていると見落とします。SQL 実行が中心の OCI Database Tools MCP や SQLcl MCP と違い、このサーバはクラウドのリソース操作まで持っているので、DB ユーザーの権限と IAM の権限の両方を検討する必要があります。
7.4. エラーからの LLM の自己修正
今回の検証では、LLM がエラーから自力で復帰する場面が 2 回ありました。
-
run_queryの必須引数connection_methodを省略して失敗 → 保存済みの接続情報からrdsapiを読み取り、指定し直して成功 - Data API 無効化中の
run_query失敗 → AWS CLI でクラスタ状態を自ら確認してHttpEndpointEnabled: Falseを特定 → 再有効化の提案と pgwire の代替案を提示
いずれも、エラーが具体的な内容(必須引数の名前、HttpEndpointNotEnabledException という例外名)で返ってきたことが、会話面での原因特定と代替案の提示につながっていました。一方で 3.5 章の起動失敗のように、MCP サーバ自体が起動できないケースはツール呼び出しの手前なので、LLM からは手の出しようがなく、サーバログの確認が必要です。
8. まとめ
| # | 検証項目 | 結果 |
|---|---|---|
| 1 | Claude Desktop から Aurora PostgreSQL に接続できる | OK。7 ツールを認識し、products の SELECT が投入 8 行と完全一致で返った |
| 2 | 接続 2 方式(rdsapi / pgwire)を同一クラスタで比較できる | OK。両方式で SQL 実行に成功し、会話中の切り替えも再起動不要。Data API 無効化で rdsapi だけが使えなくなり、pgwire は影響を受けなかった |
| 3 | 読み取り専用の構成で書き込みを防げる |
OK。INSERT・DROP とも拒否され、前後スナップショットが完全一致。ただし対象は SQL のみで、create_cluster は対象外 |
「RDS Data API が前提」という着手前の想定は外れて、実際は 3 方式から選べる設計でした。そのぶん「どの方式を選ぶか=どの前提条件を用意するか」が最初の設計ポイントになります。今回試せていない pgwire_iam(IAM 認証の直接接続)や、同じ awslabs の DynamoDB MCP Server も続きの検証候補です。
-
MCP経由でDBを触るエージェントを“端から端まで”追う ─ SQLcl MCP の監査証跡(Unified Audit)と Langfuse のトレースを突き合わせてみた ↩
-
Google の MCP Toolbox for Databases から Oracle Autonomous Database に wallet 接続してみた ↩
-
awslabs/mcp postgres-mcp-server(GitHub README) — "Connection Methods" / "Database Types" / "Security Consideration"。公式サイト版は Amazon Aurora Postgres MCP Server ↩ ↩2 ↩3 ↩4 ↩5 ↩6
-
awslabs.postgres-mcp-server(PyPI) — 検証時バージョン 1.1.7(2026-06-25 リリース) ↩ ↩2
-
Amazon RDS Data API の使用(AWS Docs) — 永続接続不要の HTTPS エンドポイントで SQL を実行する仕組み。認証情報は Secrets Manager 経由 ↩
-
Aurora Serverless v2 のゼロスケール再開時間を Platform Version 4 で再計測してみた ↩
-
RDS Data API でサポートされているリージョンと Aurora DB エンジン(AWS Docs) — Aurora PostgreSQL の表。Serverless v2・プロビジョンドとも対応 ↩
-
AWS Blog: Supercharging AWS database development with AWS MCP servers(2025-06-27) ↩
-
OCI MySQL HeatWave に OCI Database Tools MCP でつなごうとしたら、MCP は Oracle 接続限定だった(2026/6) ↩






