Claude Codeのdatabases-on-awsプラグインでAurora DSQLを設計する
AWS提供のdatabases-on-awsプラグインを入れ、dsqlスキルでAurora DSQLのスキーマ設計・クエリ実行・移行を進める手順と、MCPとpsqlの使い分け、DDLの制約、権限設定の例をまとめます。
databases-on-awsは、Amazon Web Servicesが配布するClaude Code用プラグインです。中身になっているのはAurora DSQL(サーバーレスでPostgreSQL互換の分散SQLデータベース)用の「dsql」スキルで、スキーマ設計、クエリ実行、移行、データロード、性能診断までを1つのスキルに束ねています。
入れること自体は2行で終わります。手間がかかるのは入れた後です。DSQLにはPostgreSQLと同じ感覚で書くと弾かれる規則がいくつもあり、スキルはそれをClaudeに守らせるための手順書になっています。この記事では導入、接続経路の選び方、スキーマ設計で効くルール、制限値、権限設定の順に、手を動かせる形で扱います。
databases-on-awsプラグインには何が入っているのか
プラグインは「スキル」「MCPサーバー」「フック」「スクリプト」の4つで構成されます。マーケットプレイスの説明は「スキーマ設計、クエリ実行、移行、ワークロードに合うデータベース選び」を挙げていますが、READMEによると現在対応しているのはAurora DSQLだけです。
| 部品 | 中身 |
|---|---|
スキル dsql | 中身「Aurora DSQL」「DSQL schema」「create DSQL table」「migrate to DSQL」などの語で起動する |
MCPサーバー awsknowledge | 中身AWSの文書、構成ガイダンス、ベストプラクティスの検索 |
MCPサーバー aurora-dsql | 中身クエリ、スキーマ取得、トランザクションの実行。既定では無効 |
MCPサーバー cloudwatch | 中身性能診断(ワークフロー12)用。これも既定では無効 |
| フック | 中身transact の実行後に、結果の検証を促すプロンプトを差し込む |
| スクリプト | 中身クラスタの作成・削除・一覧・情報取得、psql 接続、データロード |
起動語が「Aurora DSQL」や「DSQL schema」なので、Claudeに「DSQLでテーブルを作って」と頼むだけでスキルが読み込まれます。スキル側には、参照ファイルを読む条件も明記されています。スキーマ変更やDB操作の前には開発ガイドを必ず読む、外部キーを触るときは外部キーの文書を必ず読む、といった具合です。
導入に必要なものと手順は何か
READMEの要件は2つです。Claude Code 2.1.29以上であることと、AWS CLIが適切な資格情報で設定済みであること。psql 接続のスクリプトを使うなら psql と jq も要ります。
claude --version
aws sts get-caller-identity1行目でバージョンを、2行目でAWSの資格情報が通っているかを確かめます。次にClaude Codeのセッション内でマーケットプレイスを追加し、プラグインを入れます。
/plugin marketplace add awslabs/agent-plugins
/plugin install databases-on-aws@agent-plugins-for-aws/plugin install はセッション内では即時には入らず、/plugin パネルが該当プラグインの詳細で開き、スコープを選んで確定する流れです。反映には /reload-plugins を実行します。シェルから入れるなら claude plugin install を使い、次回の起動時か /reload-plugins で読み込まれます。
MCPで繋ぐか、psqlで繋ぐか
ここが最初のつまずきどころです。プラグインが同梱する aurora-dsql MCPサーバーは、起動時に1つのクラスタに固定されます。クラスタのエンドポイントは起動時の引数 --cluster_endpoint で渡す仕組みで、別のクラスタを使うには設定を書き換えてセッションを再起動しなければなりません。
そのためスキルは、次の判断を課しています。
どの経路でクエリを流すか
- Qaurora-dsql MCPは有効で、いま使いたいクラスタを向いているか?答えが向いていない、無効、または確認できない答えがはい
scripts/psql-connect.sh <cluster-id> --region <region> --command "SELECT ..."を使います。IAM認証トークンを発行し、psql経由で実行します。MCPを設定し直すことはしません。
MCPのツールを使う
readonly_query、transact、get_schema が使えます。どのクラスタを向いているか分からないときは、先に確認するか psql 経路に倒します。
スキルの理由づけは単純で、誤ったクラスタに書き込むほうが、確認の手間より高くつくというものです。どちらの経路でも、実行されるSQLは同じです。
MCPを有効にする
同梱の .mcp.json では、aurora-dsql は disabled: true で、エンドポイントも書かれていません。ドキュメント検索だけなら設定不要で、実クラスタを触るときに初めて引数を足します。Claude Codeのコマンドで登録する場合は、スキルの手順書が次の形を示しています。
claude mcp add aurora-dsql \
--scope project \
--env FASTMCP_LOG_LEVEL="ERROR" \
-- uvx "awslabs.aurora-dsql-mcp-server@latest" \
--cluster_endpoint "<cluster-id>.dsql.<region>.on.aws" \
--region "<region>" \
--database_user "admin"--allow-writes を付けない限り、MCPサーバーは読み取り専用で動きます。書き込みを許すかどうかは、手順書自身が「毎回ユーザーに確認する」と定めている項目です。まずは付けずに始めるのが無難です。
スキーマ設計でスキルが守らせるルール
DSQLの設計では、PostgreSQLの常識がそのまま通らない箇所があります。開発ガイドにあるルールのうち、設計に効くものを拾います。
- 1トランザクションに入れるDDLは1文まで。複数DDLは
multiple ddl statements not supported in a transactionで拒否される - スキーマ変更(DDL)とデータ変更(DML)は同じ操作に混ぜない
- インデックスは
CREATE INDEX ASYNCが必須。同期作成はできない - 配列型の列は使えない。1列にまとめる形にし、
JSONBを優先する - 列ごとの
COLLATEは付けない。DSQLはデータベース全体がC照合順序で、DDLに書くと拒否される - 切り詰めは
DELETEだけが使える - マルチテナントのテーブルには
tenant_idを持たせ、すべてのクエリのWHEREに入れる
これらの多くは単なる推奨ではなく、スキルの文面でMUST(必須)と書かれています。Claudeに任せるときの利点は、これを毎回プロンプトに書かなくて済む点です。
例: テナント付きのタスク表を作る
「複数テナントのタスク管理テーブルをDSQLで作りたい」と頼むと、スキルのワークフロー1に沿って、DDLを1文ずつ別のトランザクションで流します。例えば次のような形になります(スキルのルールに沿った形の一例です)。
-- 1回目の transact
CREATE TABLE tasks (
tenant_id uuid NOT NULL,
task_id uuid NOT NULL,
title text NOT NULL,
tags jsonb,
created_at timestamptz,
PRIMARY KEY (tenant_id, task_id)
);
-- 2回目の transact(インデックスは別呼び出し)
CREATE INDEX ASYNC idx_tasks_tenant_created
ON tasks (tenant_id, created_at);インデックスは作成直後に使えるわけではありません。非同期で構築されるので、使う前に pg_index の indisvalid が真になっているかを確かめます。真になるまでクエリは動きますが、そのインデックスは使われません。
SELECT indisvalid FROM pg_index
WHERE indexrelid = 'idx_tasks_tenant_created'::regclass;既存の表に列を足す順序
DEFAULTやNOT NULLを付けたい列は、いきなり付けられません。スキルが課す順序は次のとおりです。
DEFAULT付きの列を足す手順
- 1
名前と型だけで ADD COLUMN
ALTER TABLE ... ADD COLUMNに制約や既定値は書きません。ALTERは1文ずつ別のtransact呼び出しで流します。 - 2
UPDATE で既存行を埋める
3,000行未満のバッチに分けて流します。途中で失敗したら、新しい列がNULLの行だけを対象に再開できます。
- 3
必要なら SET DEFAULT
以後の書き込み用の既定値は、直接の
ALTER COLUMN ... SET DEFAULTで足せます。
外部キーはNOT VALIDで足してから検証する
外部キーは使えます。むしろスキルは、データベースに参照整合性を持たせたいなら既定で使う、という立場です。ただし既存の表へ後から足すときは NOT VALID が必須で、既存行の検証は別の非同期ジョブになります。
ALTER TABLE orders
ADD CONSTRAINT orders_customers_customer_fkey
FOREIGN KEY (tenant_id, customer_id)
REFERENCES customers (tenant_id, customer_id)
NOT VALID;
ALTER TABLE ASYNC orders
VALIDATE CONSTRAINT orders_customers_customer_fkey;テナント内で整合させたいときは、キーの両側に tenant_id を含めた複合外部キーにします。VALIDATE は job_id を返すので、sys.jobs を見て completed か failed を確認します。参照アクションは NO ACTION を既定にし、CASCADE は意図して選んだときだけ使います。カスケードの削除や更新は、そのぶん1トランザクションの行数上限を食うからです。
エラーの扱いも分かれます。40001(OCC。楽観ロック方式で起きる書き込みの競合)はトランザクション全体を再試行しますが、外部キー違反の 23503 を同じ再試行ループに入れてはいけません。関係そのものを直す対象だからです。
落とし穴
外部キー違反を再試行すると、同じ失敗を繰り返す
23503 は一時的な競合ではなく、参照先が存在しないという確定した違反です。再試行ループに乗せずに、参照関係かアクションを見直します。
制限値は設計の前に確かめる
DSQLの制限は、スキーマとバッチの設計をそのまま縛ります。スキルは数値を記憶で答えさせず、awsknowledge で都度確認するよう指示しています。スキルが既定値として持つ主な値は次のとおりです。
スキルが既定値として持つ主な制限
1トランザクションの変更行数
3,000
上限
1トランザクションのデータ量
10 MiB
COMMIT時に判定
トランザクション時間
5分
上限
1テーブルのインデックス
24
主キーを含む
ほかに、認証トークンの有効期限は15分、接続の最大継続時間は60分、1インデックスの列数は8、クラスタあたりの最大接続数は10,000です。
意外に効くのが10 MiBの数え方です。インデックスへの書き込みも加算されるため、行数が3,000に届かなくても超えることがあります。上限を超えたときは DETAIL: Current transaction size <n>mb > 10mb と実測値が出るので、実スキーマで1回試せばバッチの縮め方が決まります。
エラーコードの 54000 と 0A000 は、それぞれ十数種類の制限をまとめています。コードだけで原因は絞れないので、メッセージの接頭辞で照合する、というのがスキルの規則です。
dsql_lintで移行元のSQLを通す
PostgreSQLやMySQLから移すとき、既存のDDLをそのまま流すと弾かれます。そのためのMCPツールが dsql_lint で、DSQLに対する互換性を規則ベースで検査し、fix=true で自動修正も返します。例えば CREATE INDEX idx ON t (c); に対しては、ASYNC を足した CREATE INDEX ASYNC idx ON t (c); が提案されます。
読むときの注意点が1つあります。修正ステータスは fixed、fixed_with_warning、unfixable の3種類で、fixed_sql が返ってきたからといって安全とは限りません。特に fixed_with_warning は、このインデックス例のように「文が戻った時点ではまだ使えない」といった意味を含みます。カウンタの errors == 0 だけで通過判定にせず、診断の一覧そのものを見ます。
移行元別には、スキルが別々の手順を持っています。
- MySQL: 型の対応表で
AUTO_INCREMENTやENUMの代替を決める - PostgreSQL: 型の対応、GIN/GiSTなどのインデックスの変換、
ENUMからCHECKへの置き換え - ORM: Django、EF Core、Hibernate、Rails、SQLAlchemy向けに、アダプタ名とロックの注意点
遅いと感じたときの診断ルート
性能の相談は、入口で分かれます。特定のクエリを指して「このプランはなぜ遅いか」と聞くなら、EXPLAINを読む「クエリプランの説明」に進みます。クラスタ全体が遅い、遅くなった理由が不明、OCC競合が増えた、といった場合は、CloudWatchのアクティブセッション指標を見る「システム診断」が先です。迷ったらシステム診断から始め、疑わしいクエリを特定してからクエリプランの調査に渡す、というのがスキルの規則です。
システム診断は cloudwatch MCPサーバーを有効にし、クラスタと同じリージョンでPromQLが使える設定が前提になります。サーバーを足した後は、ツールを登録するためにセッションの再起動が要ります。
Claude Code側で固めておく権限設定
スキルはSQLの正しさを助けますが、実行の許可は別の層です。transact は書き込みなので、読み取り系だけを自動許可し、書き込み系は毎回確認に回す構成が組めます。プラグイン同梱のMCPサーバーのツール名は mcp__plugin_<プラグイン名>_<サーバー名>__<ツール名> の形になるので、このプラグインでは次のように書けます。
{
"permissions": {
"allow": [
"mcp__plugin_databases-on-aws_aurora-dsql__readonly_query",
"mcp__plugin_databases-on-aws_aurora-dsql__get_schema",
"mcp__plugin_databases-on-aws_aurora-dsql__dsql_lint"
],
"ask": [
"mcp__plugin_databases-on-aws_aurora-dsql__transact"
]
}
}自分で claude mcp add aurora-dsql と登録した場合は、サーバー名が aurora-dsql なので、規則は mcp__aurora-dsql__transact の形になります。どちらの名前で動いているかは、/mcp の一覧で見比べてください。
プロジェクトのCLAUDE.mdには、スキルが拾いにくい運用上の前提を書き足しておくと安定します。
## データベース(Aurora DSQL)
- 対象クラスタは <cluster-id>(<region>)。他のクラスタには書き込まない
- スキーマ変更は dsql_lint を通してから流す
- マイグレーションは1ファイル1DDL。インデックスは必ず ASYNCプラグインにはすでに transact 後の検証フックが入っています。DDLのときは get_schema でスキーマを確認し、DMLのときは影響行数が想定どおりかを確認する、という指示です。EXPLAINの場合はクエリプランの説明に続きます。フックが差し込む文面は検証を促すだけで、承認の代わりにはなりません。上の ask と併用するのが前提です。
つまずきやすい点
- MCPに実クラスタを繋ぐ前から
readonly_queryを期待してしまう。同梱のaurora-dsqlは無効で、エンドポイントもないため、設定するまで動かない - 複数クラスタを行き来したいのに、MCPを毎回書き換えてしまう。クラスタを切り替えるなら
psql-connect.shを使う - 作成したばかりのインデックスにクエリが効かない。
indisvalidが真になるのを待つ - AWS CLIの資格情報が、Bedrock用のプロファイルのままになっている。別アカウントのクラスタへ繋ぐときは、
AWS_PROFILEとAWS_REGIONを環境変数で渡す
本番利用の前に知っておくこと
READMEの冒頭には、生成AIは間違えうるので出力とコストを必ず確認するよう注意書きがあります。ベストプラクティスの欄には、生成コードをデプロイ前に確認すること、最小権限の資格情報を使うこと、生成したインフラコードにセキュリティスキャンを走らせることが挙がっています。READMEの先頭には、このリポジトリの後継としてAgent Toolkit for AWSが公開済みという案内もあり、本番ソフトウェアを作るならそちらを勧めています。このリポジトリも引き続き動き、貢献も受け付けるとされています。
DSQLの設計をClaudeに任せるときは、設計の相談とDDLの生成までをスキルに、実クラスタへの書き込みを人の承認に分ける、という線引きが現実的です。インフラ全体の構成から決めたいときはDeploy on AWSプラグイン、Lambdaまわりを作り込むならaws-serverlessプラグインが同じリポジトリにあります。PostgreSQL系のマネージドDBをつなぐ手順はAlloyDBプラグインの記事にまとめています。