データベース

PostgreSQL MCPサーバーの構成と権限設計|読み取り専用ロールとスキーマ公開範囲の決め方

PostgreSQL MCPサーバーの構成と権限設計|読み取り専用ロールとスキーマ公開範囲の決め方

AIエージェントからPostgreSQLを参照させるだけなら、接続文字列を1本渡せば動きます。詰まるのはその先です。多くの解説が起点にする参照実装 @modelcontextprotocol/server-postgres は、npm 上の最新が 0.6.2(2024-12-04公開)で止まり、公式リポジトリの src 配下からも外れました。ここでは2026年8月時点で保守が続く4系統の実装、読み取り専用をロール側で担保する手順、公開スキーマの線引き、実行時ガードと監査ログの紐づけを実装目線で並べます。プロトコル自体の仕組みはMCPの規格とサーバーの役割を整理した記事に譲ります。

まとめ:読み取り専用で通す構成と、先に決める5つの値

最初に決めるのは実装の銘柄ではなく、読み取り専用をどの層で担保するかです。MCPサーバー側のフラグは事故を減らしますが、SQLを直接実行できるツールが露出している以上、防御の最終線になりません。書き込み権限を持たないロールで接続すれば、サーバー実装が何を許していても書き込みは失敗します。

決める値は5つ。接続に使うロール、そのロールに見せるスキーマ、1クエリの実行時間上限、トランザクションの放置時間上限、実行記録の残し先です。ここを先に固めれば、実装は入れ替え可能な部品になります。

実装は読み取り制御をどこで持つかで分かれます。Postgres MCP Pro は自前運用向け、AWS Labs版は Aurora と RDS 前提、Supabase はホスト型でURLのクエリ指定、MCP Toolbox は実行できるSQLを設定ファイルへ固定する方式です。任意のSQLを触らせたくない業務なら、4つ目がそのまま答えになります。

PostgreSQL MCPサーバーの構成要素と参照実装が保守対象から外れた現状

前提を揃えます。ここを誤ると、更新の止まった実装に依存する構成になります。

MCPクライアント・サーバー・データベースの3層と責務の切れ目

構成は3層です。MCPクライアント(Claude Desktop、Cursor、VS Code など)、PostgreSQLへ接続してツールを公開するMCPサーバー、そしてPostgreSQL本体。クライアントはモデルが選んだツールを呼び出すだけで、SQLの安全性を判断しません。

責務の切れ目はMCPサーバーとデータベースの間にあります。サーバーは「どのツールを見せるか」を決め、PostgreSQLは「そのロールに何を許すか」を決めます。前者はプロンプト次第で揺らぎ、後者は揺らぎません。設計の重心は後者へ寄せます。基礎概念はデータベースの種類とDBMSの選び方をまとめた記事に譲ります。

参照実装が 0.6.2 で停止し archived へ移管された経緯と影響

日本語の解説の多くが npx -y @modelcontextprotocol/server-postgres という起動コマンドを載せています。このパッケージは npm registry 上の最新が 0.6.2、公開日は 2024-12-04 でした。2026年8月時点で1年8か月以上、新しい版が出ていません。

公式リポジトリ modelcontextprotocol/servers の src 配下に残るのは everything、fetch、filesystem、git、memory、sequentialthinking、time の7本だけです。README の Archived 節に、PostgreSQL は GitHub や Redis などと並んで servers-archived へ移されたと明記されています。機能自体は当時から妥当でしたが、保守されない実装を業務システムの接続口に据える判断にはなりません。

2026-07-28版でセッションと初期化交渉が消えたことの影響

仕様も動いています。リビジョンは 2024-11-05、2025-03-26、2025-06-18、2025-11-25、2026-07-28 と重なり、直近の版で Streamable HTTP からプロトコルレベルのセッションと Mcp-Session-Id ヘッダが消えました。initialize のハンドシェイクも廃止され、版と能力の交渉は server/discover と各リクエストの _meta が担います。

接続設計で効くのは、サーバーが接続単位の状態を持てない点です。カーソルのように呼び出しをまたぐ状態は、サーバーが発行したハンドルをツール引数で受け渡す形へ組み替えます。Python SDK は v2.1.1(2026-08-25)まで来ており、2.0 で mcp.server.fastmcp が削除されました。Postgres MCP Pro が 2026-08-16 のコミットで mcp[cli] を 2.0 未満へ固定したのは、その暫定対応です。

実装4系統の比較|読み取り制御をどの層で担保するかという判断軸

保守が続く選択肢を、機能の多寡ではなく「読み取り制御をどこで持つか」で並べます。

Postgres MCP Pro の restricted モードと9本のツール構成

crystaldba/postgres-mcp(Postgres MCP Pro)は、自前運用のPostgreSQLへ接続する汎用サーバーです。PyPIのタグは v0.3.0(2025-05-16)ですが、コミットは 2026-08-16 まで続いています。--access-mode=restricted で読み取り専用トランザクションに限定され、実行時間の上限も課されました。unrestricted は読み書き可で、開発環境向けの位置づけです。

公開ツールは9本。list_schemas、list_objects、get_object_details、execute_sql、explain_query、get_top_queries、analyze_workload_indexes、analyze_query_indexes、analyze_db_health です。get_top_queries は pg_stat_statements に依存し、拡張が入っていない環境では使えません。返る計画の読み方はEXPLAIN ANALYZEと見積もり乖離の診断をまとめた記事が前提知識になります。

AWS Labs版の allow_write_query と2種類の接続方式の使い分け

awslabs.postgres-mcp-server は Aurora PostgreSQL と RDS for PostgreSQL に寄せた実装で、PyPI の最新は 1.1.11(2026-08-10)です。書き込みは --allow_write_query を明示的に付けたときだけ有効になります。既定が読み取り側に倒れている点は、社内へ配布する設定ファイルを書くうえで扱いやすい仕様でしょう。

接続方式は2つ。RDS Data API 経由と、通常のプロトコルでつなぐ pgwire です。前者はIAMの資格情報とシークレットで認証が完結し、接続文字列にパスワードを書かずに済みます。マネージド側の構成条件はRDS for PostgreSQLのマルチAZ構成と拡張機能の統制を整理した記事にまとめました。

Supabaseのホスト型サーバーと read_only 指定が効く範囲

Supabase は自前でプロセスを起動しない方式へ寄せています。接続先は https://mcp.supabase.com/mcp で、project_ref、read_only=true、features=database,docs といったクエリ文字列で挙動を指定します。

注意したいのは、クライアント側にも readOnly の指定がある点です。こちらは更新系ツールを一覧から除くだけで、サーバーが読み書き可のまま公開されていれば防御になりません。ホスト型で指定できるクエリの全量とスコープの引き方はSupabase MCPサーバーの接続手順とスコープ設計にまとめました。

MCP Toolbox がSQLを設定ファイルへ固定する方式と制約

googleapis/genai-toolbox(MCP Toolbox for Databases)は方向性が異なります。最新は v1.9.0(2026-08-14)。tools.yaml に接続先を kind: source、type: postgres として書き、ツールは type: postgres-sql として statement にSQL文そのものを記述します。実行されるのは書いたSQLだけです。

つまりエージェントは任意のSQLを書けません。「顧客名で検索する」といった業務単位のツールを並べる設計になり、公開範囲がYAMLの差分としてレビュー可能になります。自由な探索は消えますが、対象が個人情報や金額を含むテーブルなら、この不便さのほうが妥当でしょう。

4系統の担保層・任意SQLの可否・適する場面を1枚に並べた比較

「読み取り制御の担保層」は、書き込みを止める仕組みが実際にどこへ置かれるかを指します。

実装 読み取り制御の担保層 任意SQL 適する場面
Postgres MCP Pro 起動フラグと接続ロール 可 自前運用の調査と診断
AWS Labs版 起動フラグの有無 可 Aurora・RDSの参照
Supabase ホスト型 接続URLのクエリ指定 可 Supabase上の開発
MCP Toolbox 設定ファイルのSQL定義 不可 業務データの限定公開

調査や性能診断が目的で、対象が開発環境やレプリカなら Postgres MCP Pro。本番の業務データを扱い、探索させる必要がないなら MCP Toolbox。この2つで大半は決まります。

読み取り専用をロールで担保する理由と、サーバー側フラグの限界

「読み取り専用モードで起動したから安全」という理解は、PostgreSQLの仕様と噛み合っていません。

読み取り専用トランザクションが回避されうる経路と、実際に効く対処

PostgreSQLには、接続やセッションそのものを読み取り専用へ固定する仕組みがありません。そのため多くのMCPサーバーは読み取り専用トランザクションで代替します。Postgres MCP Pro の設計文書はこの点を率直に書き、ROLLBACK を発行して新しいトランザクションを始められると回避されうる、安全でない手続き言語が有効なら保護も迂回されうる、と説明しました。

だから対処は単純です。書き込み権限を持たないロールで接続します。権限はプロンプトの言い回しで変わりません。INSERT の権限がなければ、どんな順序でSQLを送っても書き込みは失敗します。サーバー側のフラグは、事故を早い段階で止める一段目として併用してください。

専用ロール作成の手順と、15以降で変わった public の既定

MCP専用ロールは、既存の参照用ロールを流用せず新規に切ります。誰が何を見たかを後から切り分けるためです。

  1. ログイン可能なロールを作る(CREATE ROLE mcp_reader LOGIN PASSWORD ...)
  2. 対象データベースへの接続を許す(GRANT CONNECT ON DATABASE ...)
  3. 公開するスキーマにだけ USAGE を与える
  4. そのスキーマの既存テーブルに SELECT を与える
  5. ALTER DEFAULT PRIVILEGES で今後作られるテーブルにも SELECT を自動付与する

4番目で止めると、運用開始後に追加されたテーブルが見えず、原因調査に時間を取られます。5番目まで含めて一組です。なお PostgreSQL 15 以降、public スキーマの CREATE 権限は既定で全ロールから外れました。14以前から引き継いだデータベースではこの既定が適用されないため、REVOKE CREATE ON SCHEMA public FROM PUBLIC を明示的に流してください。組み合わせの詳細はCREATE ROLEの属性と既定権限の決め方を整理した記事で扱っています。

列単位のGRANTとビュー経由の公開で機微な項目を外す2つの方法

テーブル単位の SELECT では粗すぎる場面があります。会員テーブルに氏名や電話番号があり、集計だけさせたいときです。GRANT SELECT (id, created_at, plan) ON members のように列を指定するか、必要な列だけを出すビューへ SELECT を与えるかの2択になります。

実務では後者を勧めます。列指定では SELECT * がエラーになり、エージェントが繰り返し失敗して無駄な往復が増えるからです。ビューなら定義が1か所へ集まります。行単位で絞りたい場合は行レベルセキュリティを併用しますが、ポリシーが増えると挙動の追跡が難しくなるため、まずはビューで足りるかを確かめてください。

スキーマ公開範囲の絞り込みと、接続設定・実行時ガードの具体値

ロールを作ったら、見せる範囲と、暴走したときの止め方を決めます。ここを空欄のまま本番へ向けると、1本の重いクエリで巻き添えが出ます。

公開スキーマの分け方と search_path をロールへ固定する運用

公開範囲はスキーマ単位で切るのが管理しやすい形です。参照させたいビューを専用スキーマ(例:agent)へ集め、そのスキーマにだけ USAGE を与えます。元テーブルへの直接の SELECT は与えません。

あわせて ALTER ROLE mcp_reader SET search_path = agent で探索パスを固定します。スキーマ名を省いたSQLが、意図しないスキーマの同名テーブルへ当たる事故を防げるからです。解決順の挙動とテナント分割の判断基準はsearch_pathの解決順とpublic権限を扱った記事にまとめました。

接続文字列に平文のパスワードを置かないための3つの選択肢と優先順

クライアント設定のJSONに postgresql://user:password@host をそのまま書く例が広く出回っていますが、この文字列は端末に残り、バックアップにも入ります。代替は3つ。パスワードファイル(.pgpass)へ寄せる、環境変数に入れて設定側では参照だけにする、IAM認証やRDS Data APIのように静的なパスワードを使わない、です。

優先順位は3つ目、2つ目、1つ目の順になります。Aurora や RDS なら、AWS Labs版の Data API 接続を選ぶだけで静的な資格情報が構成から消えました。オンプレミスではパスワードファイルへ寄せ、ファイル権限を600に絞ってください。通信路の保護は別で、TLSはPostgreSQLの暗号化とTLS設定を扱った記事で触れています。

実行時間・放置トランザクション・接続数へ置く上限値4種の目安

エージェントは平気で全件走査のSQLを書きます。ロール単位で上限を固定しておけば、実装を入れ替えても効き続けます。

設定 目安 狙い
statement_timeout 30秒 重いクエリの打ち切り
idle_in_transaction 60秒 放置トランザクション解消
CONNECTION LIMIT 5 接続の食い潰し防止
lock_timeout 5秒 ロック待ちの長期化回避

いずれも ALTER ROLE mcp_reader SET ... で固定します。30秒は、対話的な調査で人間が待てる上限とほぼ同じ値です。バッチ的な集計を任せたいなら、別ロールを切って値を伸ばすほうが、対話用ロールを緩めるより安全でしょう。読み取り専用でも放置トランザクションの上限は要ります。開きっぱなしのトランザクションが、不要行の回収を止めてしまうからです。

社内データを扱うときの監査ログ設計と権限の紐づけ方の判断基準

権限を絞ったら、次は記録です。「エージェントが何を見たか」を後から言えない構成は、社内の情報資産を扱う段階で承認が下りません。

application_name でMCP経由の実行を識別して記録に残す設計

application_name を mcp-agent のような固定値にしておくと、pg_stat_activity とログの両方でMCP経由の実行だけを抽出できます。log_line_prefix に %a と %u を含めておくのが前提です。

実行内容そのものを残すなら log_statement を all にする方法が手軽ですが、対象データベース全体のログ量が増えます。MCP用ロールだけに絞るなら ALTER ROLE mcp_reader SET log_statement = 'all' と設定してください。より細かい単位なら pgaudit 拡張でセッション監査を該当ロールへ限定します。取得の自動化はpg_dumpとPITRの使い分けをまとめた記事が参考になります。

共有ロールと利用者ごとのロールを分ける判断基準と運用上の手数

全員が同じ mcp_reader で接続する構成は、配布が楽な代わりに、ログを見ても誰の指示による実行か分かりません。基準は明快です。参照先に個人情報・人事情報・取引条件のいずれかが含まれるなら、利用者ごとにロールを切ります。

その場合は共通の権限を持つグループロールを1つ作り、個人のロールをそこへ所属させます。権限の変更はグループ側だけで済み、退職時は個人ロールを削除するだけで参照が止まりました。

PostgreSQL MCPサーバーを採用してよい条件と、見送るべき場面

この構成は万能ではなく、向く仕事と向かない仕事がはっきり分かれます。

採用してよい3条件と、ロール切り出しの手間に見合う具体的な業務

採用してよいのは、次の3条件がそろったときです。第一に、参照先が開発環境・レプリカ・分析用データベースのいずれかであること。第二に、読み取り専用ロールと公開スキーマを切る作業が1日以内で終わる程度にスキーマが整理されていること。第三に、質問する人がSQLを書けない、または待ち時間が惜しい状況が常態化していること。

典型は問い合わせ対応中の事実確認です。「この会員はいつからどのプランか」を調べるため開発者へ依頼が飛ぶ運用は、参照用ビューを数本用意して見せるだけで消えます。

見送るべき3つの場面と、そこで代わりに選ぶべき手段の具体的な形

1つ目は、本番データベースへ書き込みを許す構成です。エージェントの UPDATE は条件節を1つ落とすだけで全行に当たり、しかも当人はその誤りを検知できません。書き込みが必要な業務は、任意のSQLではなくAPIとして手続きを固定してください。

2つ目は、個人情報や取引条件を含むテーブルへ任意のSQLを通す構成。ここは MCP Toolbox for Databases のようにSQLを設定ファイルへ固定する方式へ切り替えます。3つ目は、スキーマが整理されていない状態での導入です。命名から意味が読み取れないデータベースでは、エージェントが誤った結合を平然と返し、検証に人間の時間がかかります。ビューによる整理か命名の見直しが先になります。

迷う場合は、参照範囲を最小のビュー数本へ絞って2週間動かし、ログを確認してから広げる進め方を勧めます。設計と権限の切り出しを外部に任せたいときは、AIエージェント開発で接続先の選定から監査設計まで対応しています。

よくある質問

実装の選定と権限まわりで、実際に問い合わせの多い5点をまとめます。

PostgreSQL用のMCPサーバーに公式のものはありますか?

modelcontextprotocol の組織が出していた参照実装 @modelcontextprotocol/server-postgres は、servers-archived リポジトリへ移されました。npm 上の最新も 0.6.2(2024-12-04公開)で止まっています。Aurora や RDS なら AWS Labs版、Supabase ならホスト型、自前運用なら Postgres MCP Pro が候補になります。

読み取り専用モードで起動すれば書き込みの心配はなくなりますか?

なくなりません。PostgreSQLには接続そのものを読み取り専用に固定する仕組みがなく、多くの実装は読み取り専用トランザクションで代替しています。Postgres MCP Pro の設計文書も、ROLLBACK を挟んで新しいトランザクションを始める経路で回避されうると明記しました。書き込み権限を持たないロールで接続することが、実際に効く防御です。

本番のデータベースに直接つないでも問題ありませんか?

参照のみで、公開範囲をビューで絞り、実行時間の上限を置いているなら実務上は成立します。ただし読み取りでも負荷は生じるため、レプリカがあるならそちらへ向けるのが無難でしょう。

Aurora PostgreSQLやRDSでも同じ手順で使えますか?

ロールと権限の設計はそのまま通用します。接続方法だけが違い、AWS Labs版なら RDS Data API 経由と pgwire 経由を選べます。マネージド側ではスーパーユーザー権限が制限されるので、拡張の導入可否を先に確認してください。

MCPサーバーはローカルとサーバーのどちらで動かすべきですか?

利用者が数人で対象が開発環境なら、各自の端末で起動する形で足ります。人数が増える、あるいは本番系を参照するなら、サーバー側に置いて接続情報を1か所へ集めるほうが管理できるでしょう。

関連記事

お気に入りに入れた記事の一覧

この記事は以下の記事からリンクされています

資料請求

今日のトレンド記事 直近 24 時間で、いつもより多く読まれている記事

  1. 2026.10.09 テックブログ IDCFクラウド(IDCフロンティア)不正アクセス・ランサムウェア:影響先・復旧・データは戻るか
  2. 2026.10.09 テックブログ ニッスイのサイバー攻撃で日水物流の入出荷停止|委託先クラウド障害に荷主が備える手順
  3. 2026.10.09 テックブログ 京王電鉄のランサムウェア被害とグループ共通基盤:決済・ポイント・予約が止まった範囲と遮断の初動
  4. 2026.10.09 テックブログ スタディサプリの不正アクセスとメールアドレス3,687件|アカウント列挙を防ぐ実装
  5. 2026.10.08 コラム 雇用保険の適用拡大:2028年10月の週10時間以上への変更と、勤怠・労務システムで直す判定ロジック

RELATED POSTS 関連記事

目次