pgmcp
pgmcp
pgmcp は、Model Context Protocol 向けの読み取り専用 PostgreSQL 運用/DBA サーバーであり、公式の modelcontextprotocol/go-sdk 上に構築されています。インシデント対応中に DBA が口にするような質問——どのステートメントが遅いのか、このプランがなぜ遅いのか、どのインデックスが無駄な重荷になっているのか、どのテーブルで autovacuum が追い付いていないのか、誰が誰をブロックしているのか、スタンバイの遅延がどのくらいあるのか——に答えます。そして pgmcp は、慣習ではなく読み取り専用という構造によって安全性を保っています。具体的には、書き込み権限を持たない専用のデータベースロール、すべてのステートメントにステートメントタイムアウトを課した BEGIN READ ONLY トランザクション、そして SELECT/EXPLAIN/SHOW のいずれか1つ以外のものと、読み取り専用トランザクションの内部から状態を変更し得るすべての関数を拒否する SQL パーサーガードを備えています。PostgreSQL 16 でテスト済みで、13 以降が必要です。
インストール
Claude Desktop(ワンクリック) —— Releases から pgmcp_<version>.mcpb をダウンロードして開きます。Claude Desktop が Postgres の接続文字列を要求し、それを OS のキーチェーンに保管して、同梱のバイナリを自ら起動します。PATH に何かを追加する必要も、編集する設定ファイルもありません。1つのバンドルで macOS(ユニバーサル)と Windows(x64)の両方に対応します。
それ以外の場合は、Releases からお使いのプラットフォーム用のバイナリをダウンロードしてください——darwin、linux、windows と、amd64、arm64 の組み合わせで、チェックサム付きです。
または、Go の CLI ツール go を使ってソースからビルドします:
go install github.com/pascalallen/pgmcp/cmd/pgmcp@latestまたは、リリース済みイメージを実行します。このイメージは distroless、非 root、マルチアーキテクチャ対応です:
docker run --rm -i -e PGMCP_DATABASE_URL='postgres://…' ghcr.io/pascalallen/pgmcppgmcp は MCP レジストリに io.github.pascalallen/pgmcp として登録されています。
何かに接続する前に、まず読み取り専用ロールを作成してください(Database role を参照)。このロールは、他の2つの層にバグがあった場合でも、それでも機能を維持する層です。
Related MCP server: PostgreSQL MCP Server
使い方
MCP のサーフェスは1つ、トランスポートは2つです。どちらを実行するかは設定の問題であり、別のビルドを使うわけではありません。
Claude Code(stdio) —— クライアントがバイナリを起動し、stdin/stdout で通信します:
claude mcp add pgmcp --transport stdio \
--env PGMCP_DATABASE_URL='postgres://pgmcp:…@db.internal:5432/app?sslmode=require' \
-- pgmcpClaude Desktop(stdio) —— Releases から .mcpb バンドルをインストールするか(インストールを参照)、または同じ内容を手動で claude_desktop_config.json に書き込みます:
{
"mcpServers": {
"pgmcp": {
"command": "pgmcp",
"env": {
"PGMCP_DATABASE_URL": "postgres://pgmcp:…@db.internal:5432/app?sslmode=require"
}
}
}
}HTTP —— 共有デプロイメント向けに、静的なベアラーキーの背後で提供される Streamable HTTP。pgmcp は平文の HTTP を話し、TLS を自ら終端することはありません。リバースプロキシの背後にあるループバック上で実行してください。
PGMCP_DATABASE_URL='postgres://pgmcp:…@db.internal:5432/app?sslmode=require' \
PGMCP_AUTH_MODE=static \
PGMCP_API_KEYS="$(openssl rand -hex 32)" \
pgmcp --transport http --listen 127.0.0.1:8080claude mcp add pgmcp --transport http https://pgmcp.example.com/mcp \
--header "Authorization: Bearer <key>"TLS 終端、ストリーミングトランスポートが必要なプロキシ設定、ID プロバイダーに対する JWT 認証、pgmcp を claude.ai のカスタムコネクタとして配線する方法は、すべて docs/DEPLOYING.md に記載されています。
ツール
ツール | 答えを返す質問 |
| サーバー全体でどのステートメントが遅い、あるいはコストが高いか? |
| このステートメントの問題が遅いのか?プランツリー、self time を最も多く消費しているノード、プラン警告、そして後からの実行結果と差分を取るための安定した |
| どのインデックスを削除でき、どのインデックスが役割を果たしていないか? 一度もスキャンされていないインデックス、重複インデックス、無効なインデックス、肥大化インデックスを検出します。 |
| autovacuum はどこで提供作業から遅れているのか? デッドタプル比率、最後の vacuum/analyze、シーケンシャルスキャンとインデックススキャンの比較、テーブルごとの推定肥大化を表示します。 |
| このクエリはなぜハングしているのか? 現在のロック待ちグラフ——誰がブロックされ、誰がその人をブロックスしているのか、デッドロックに相当するサイクルがあるかどうかを表示します。 |
| サーバーは今何を実行していて、 |
| スタンバイはどれほど遅延しているか、どのスロットが WAL を保持している? プライマリ/スタンバイの役割、スタンバイごとの遅延(バイト数とミリ秒)、スロット状況、現在の WAL レートを表示します。 |
| このサーバーのチューニングは妥当か? |
| 残りの8つのツールが扱わないすべてを扱います。 |
すべてのツールには readOnlyHint: true、destructiveHint: false、idempotentHint: true、openWorldHint: false の注釈が付けられ、型付けされた出力スキーマを返します。
query は自由形式のSQLを持つ唯一のツールであり、任意です。--disable-query を指定すると、このツールはカタログから完全に削除されます——8つの診断ツールだけが必要なデプロイは、一時的な SQL のためのサーフェスを一切持ちまずに運用できます。--query-schemas=public,app は、代わりに query を指定したスキーマに制限し、explain についても同じように制限します。analyze=true はステートを実行するからのです。この制限が何を防ぎ、何を防ぎないのかは、docs/SECURITY.md を読んでください。
リソースとプロンプト
リソース | 内容 |
| 最初に確認するサーバーのスナップショット:バージョン、稼働時間、リカバリ状態、インストール済み拡張機能、データベースごとのサイズ、キャッシュヒット率、 |
| 生の |
プロンプト | 引数 | 目的 |
|
| 4つのステップからなる調査です:ステートメントを |
設定
すべての設定には --flag と PGMCP_<KEY> 環境変数があります。フラグは環境変数よりも優先しく、環境変数はデフォルト値より優先します。設定エラーは、問題のあるすべてのキーを1つのメッセージに列挙して終了コード 2 で終了し、実行時の失敗は終了コード 1 で終了します。
フラグ | 環境変数 | デフォルト | 意味 |
|
| —(必須) | Postgres 接続文字列 |
|
|
|
|
|
|
| HTTP の待ち受けアドレス |
|
| — | OAuth リソースメタデータのためにこのサーバーが到達可能な公開オリジン |
|
|
|
|
|
| — | カンマ区切りの静的 API キー。 |
|
| — | JWK セットのURL。 |
|
| — | 必要な |
|
| — | 必要な |
|
| — | RFC 9728 に従って外部に公開する OAuth 認可サーバー(カンマ区切り) |
|
|
| アドホックな |
|
| — |
|
|
|
| Postgres への最大接続数 |
|
|
| ツール呼び出しあたりのタイムアウト |
|
|
| ツール呼び出しの構造化コンテンツの上限 |
|
|
| 主体あたり・1分あたりのツール呼び出し数(HTTP のみ) |
|
|
|
|
|
|
|
|
|
|
| ループバック以外の待ち受けアドレスで |
| — | — | バージョンを表示して終了する |
認証ブロックはHTTPトランスポートにのみ適用されます。stdioでは、呼び出し元が誰であるかを決定するのはオペレーティングシステムです。バイナリを起動した親プロセスだけであり、他の誰でもありません。
セキュリティモデル
読み取り専用を3つの独立した方法で実現。 書き込み権限を持たない専用ロール(
pg_monitorにSELECTを付与し、意図的にpg_signal_backendは付与しない)。アダプタが実行するすべてのステートメントの周囲でBEGIN READ ONLYとSET LOCAL statement_timeoutおよびlock_timeout = '2s'を使用し、常にロールバックする。そしてパーサーレベルのガード。読み取り専用トランザクションだけではpg_terminate_backend、pg_read_file、pg_sleep、setvalを止められないためです。SQLガードは許可リスト優先。 トップレベルのステートメントは1つだけで、
SELECT、EXPLAIN、SHOWのいずれかでなければならない。ツリー内のどこにもネストされた書き込みステートメントがないこと。FOR UPDATE/FOR SHAREロック句がないこと。SELECT INTOがないこと。そして拒否された関数の呼び出しがないこと(ファイルアクセス、バックアップとWAL制御、レプリケーションスロット、アドバイザリロック、dblink、シーケンス変更、統計リセット)。スキーマ許可リストはガードレールであり、境界ではない。
--query-schemasは、解析されたステートメント内のテーブル参照に該当するスキーマを大文字小文字を区別せずに照合し、呼び出し元が提供するSQLを運ぶ両方のツール(queryとexplain)を制限するため、analyze=trueを指定したexplainは除外したスキーマに対して実行できません。許可されたスキーマ内のビュー、集合を返す関数、またはSECURITY DEFINER関数は、その外側を読み取ることができます。データベースの権限が境界であり、許可リストは明白な経路を狭めるだけです。認証され、フェイルクローズで、HTTP経由。 静的キーは、早期終了なしに保存されたすべてのハッシュに対して定時間で比較されます。JWTは、非対称アルゴリズムのみ(
alg=noneなし、HMAC混乱なし)のJWKセットと、必須のiss、aud、expに対して検証され、検証器はJWKSが到着するまでキーを保持しないため、オープンではなくクローズドで開始します。RFC 9728の保護されたリソースメタデータは、トークンを取得する場所を広告します。サーバーは、認証オフでループバック以外のアドレスでは起動を拒否します。制限付き。 プリンシパルごとのレート制限、呼び出しごとのタイムアウト、トランザクション内のステートメントタイムアウトとロックタイムアウト、
queryツールの行数上限、結果の構造化コンテンツの上限、および1 MiBのリクエストボディ制限。機密情報はログに記録されない。 ツール呼び出しは、その名前、期間、結果、呼び出し元のユーザーIDをログに記録しますが、引数、SQLテキスト、結果行、エラーテキストは決して記録しません。解析失敗は、ステートメントをエコーするのではなく固定フレーズで返され、DSNは接続エラーから編集されます。
脅威モデル、レイヤーの完全な列挙、および各レイヤーがカバーしない制限は、docs/SECURITY.md にあります。
テスト
レース検出器とカバレッジを有効にしてテストスイートを実行します:
go test -race -cover ./...統合テストにはPostgresデータベースが必要で、PGMCP_TEST_DSN が設定されていない場合はスキップされます。pg_stat_statements がプリロードされたスクラッチPostgresに対して実行するには:
docker run -d --rm --name pg -e POSTGRES_PASSWORD=postgres -p 5544:5432 postgres:16 \
-c shared_preload_libraries=pg_stat_statements -c pg_stat_statements.track=all
docker exec pg psql -U postgres -c "CREATE EXTENSION IF NOT EXISTS pg_stat_statements"
PGMCP_TEST_DSN="postgres://postgres:postgres@localhost:5544/postgres?sslmode=disable" go test -race -cover ./...カバレッジプロファイルを作成して表示します:
go test -covermode=count -coverprofile=coverage.out ./...
go tool cover -html=coverage.out公式のMCP適合性スイートで実行中のサーバーを駆動するか、Inspectorでスモークテストします:
npx -y @modelcontextprotocol/conformance server --url http://127.0.0.1:8080/mcp \
--expected-failures .github/conformance-expected-failures.yaml
npx @modelcontextprotocol/inspector --cli http://127.0.0.1:8080/mcp --transport http --method tools/list貢献
プルリクエストは歓迎します。大きな変更については、まずissueを開いて変更内容を話し合ってください。
テストを適宜更新してください。
ライセンス
This server cannot be deployed
Maintenance
Related MCP Connectors
Hosted MCP server for PostgreSQL diagnostics: slow queries, missing indexes, connection pressure.
Comprehensive PostgreSQL documentation and best practices, including ecosystem tools
- dataOAuthco.thinair
PostgreSQL, MySQL, and SQL Server in one session. 26 read-only MCP tools for AI agents.
Related MCP Servers
- -licenseNot gradedqualityAmaintenanceA Model Context Protocol server that provides read-only access to PostgreSQL databases. This server enables LLMs to inspect database schemas and execute read-only queries.97,848 npm91,120MIT
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol server providing LLMs read-only access to PostgreSQL databases for inspecting schemas and executing queries.97,848 npm27MIT
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that provides AI assistants with secure, read-only access to PostgreSQL databases while offering comprehensive tools for schema exploration, query validation, and performance optimization.MIT
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol server providing read-only access to PostgreSQL databases, enabling LLMs to inspect database schemas and execute read-only SQL queries.97,848 npmMIT