pg-analytics-mcp
pg-analytics-mcp
設定駆動型の読み取り専用Postgres MCPサーバー(Claude向け)。Streamable HTTP経由でPostgresスキーマをClaudeに公開します。スキーマとenum値は起動時にライブデータベースからイントロスペクトされ、クライアント固有の設定はすべて単一のYAMLファイルにまとめられます。
cloudflared → リバースプロキシ構成のCloudflare Accessの背後で動作するように設計されています(完全なプロビジョニング手順書が含まれています)。ただし、サーバー自体にCloudflareへの依存はなく、どこでも動作します。
クライアント非依存。 server/ 配下には、特定のクライアントを知るものは何もありません。新しいクライアントに対応するには: リポジトリをコピーし、設定ファイルを書き、.env を設定します。
なぜ存在するのか
先行実装は、ベンダーパッケージを回避するために3つのプロセスを積み重ねていました:
supergateway → enrich.py → postgres-mcp → Postgrespostgres-mcp は stdio/SSE のみに対応しており(CloudflareはStreamable HTTPを要求します)、設定面がまったくありません。さらに supergateway はMCPセッションごとに子プロセスをフォークしましたが、その子プロセスは回収されることがなく、ロール上限20に対して 子プロセス23 / 接続15 を計測しました。これは「約9回の呼び出しは成功するが、その後は SELECT 1 を含めてすべて失敗する」という形で表面化しました。
このサーバーは1つのプロセスと1つの共有プールで構成されます。計測結果: 30回のツール呼び出し後も1プロセスです。
Related MCP server: Brand MCP Server
アーキテクチャ
Claude → portal.<zone> Cloudflare MCP Server Portal (OAuth)
→ mcp-origin.<zone> Access app + Managed OAuth
→ cloudflared tunnel
→ traefik Host-header routing
→ this container uvicorn, Streamable HTTP at /mcp
→ Postgres read-only role → analytics.* viewsセキュリティ境界はデータベースロールであり、このサーバーではありません。
クイックスタート
cp .env.example .env # set DATABASE_URI + the deployment vars
$EDITOR config/example.yaml # domain prose for this client
docker compose up -d --build
curl -s localhost:8000/healthz # ok
curl -s localhost:8000/introspection # what the server decided at bootCloudflare側については、docs/PLAYBOOK-NEW-CLIENT.md に従ってください。
設定
.env — ホスト固有のもので、VPS間で変わる唯一のものです:
変数 | 目的 |
| 読み取り専用ロール。Supavisorプーラーでは、ユーザー名に |
| コンテナ、イメージタグ、traefikルーター名 |
| 公開ホスト名。トランスポートセキュリティの許可リストに自動追加されます |
| traefikが監視する外部Dockerネットワーク |
| イメージ内のクライアントYAMLへのパス |
| ホスト側の公開ポート(デフォルト8000) |
config/<client>.yaml — ドメインです。ここに列やenum値を列挙しないでください: これらは起動時にライブデータベースからイントロスペクトされるため、古くなることはありません。イントロスペクションでは知り得ないこと、つまりビジネス上の意味と落とし穴だけを書いてください。
ツール
組み込み:
execute_sql(sql)— 生の読み取り専用SQL。その説明は、起動時にあなたが作成した散文に加えて、生成されたスキーマとenumリストから組み立てられます。list_views()— 列、行数、enumを含む、読み取り可能なすべてのオブジェクト。describe_view(name)— 1つのオブジェクトの列。
設定で定義: tools.queries の各エントリは、型付きパラメータを持つ実際のMCPツールになります。パラメータはpsycopgの名前付きプレースホルダーを介してバインドされます — 文字列補間は決して使われません — また min/max はバインド前に強制されます。
tools:
queries:
monthly_trend:
description: |
Donations per month. The most recent month is PARTIAL.
params:
months: {type: integer, default: 6, min: 1, max: 36}
sql: |
select ... where donated_at >= date_trunc('month', now())
- make_interval(months => %(months)s - 1)これがn8nとのギャップを埋める部分です: ツールの追加は散文+SQLであり、Pythonではありません。
なぜ説明がここにあるのか
ツールの説明は、モデルがツールが利用可能なときはいつでも目にする唯一のコンテキストです — すべてのクライアント、すべての会話において、スキルの読み込みもプロジェクトの指示もありません。外部ドキュメントに置かれたドメイン知識は、モデルがしばしば持っていない知識です。
各説明の半分は作成されたもの(判断)、半分は生成されたもの(事実)です。生成された半分があるからこそ、boxy プラットフォーム/プロセッサと daily 頻度は、これに先立つ手書きのプロンプトで欠落していたようには、もう欠落し得ないのです。
運用
curl -s localhost:8000/introspection | python3 -m json.tool # objects, enums, tools, limits
docker top <container> # must stay at 1 process
docker compose up -d --build # after a config edit設定やスキーマの変更には再起動が必要です — イントロスペクションは意図的にプロセスの生存期間中キャッシュされるため、実行中に動作がずれることはありません。
5つの境界テスト
ビュー、権限、設定を変更した後は再実行してください。5つすべてが失敗しなければなりません:
update donations set amount = 0 where false; -- permission denied for view
select count(*) from public.donations; -- permission denied for table
select count(*) from public.website_orders; -- permission denied for table
create table analytics.t (id int); -- read-only transaction
select phone_number from customers limit 1; -- column does not existlimits.select_only は存在しますが、デフォルトはオフです: ロールが境界であり、その上にSQLバリデータを重ねると、有効な読み取り専用構文を無益にブロックしてしまいます — それが postgres-mcp の制限モードが廃止された理由です。
血を払って学んだ落とし穴
Composeのラベルキーは変数置換されません。 ラベルはリスト形式(
- "traefik...=value")でなければなりません。そうしないと、文字通り${MCP_CONTAINER_NAME}という名前のルーターになり、traefikが404を返します。DNSリバインディング保護はMCP SDKでデフォルトで有効です。 プロキシの背後で転送される
Hostを許可する必要があります。MCP_HOSTNAMEとMCP_LOCAL_PORTは自動的に追加されます。独自のStarletteの下にMCPアプリをマウントすると、そのライフスパンが置き換わります。 セッションマネージャーを明示的に起動する必要があります(
server.session_manager.run())。そうしないと、すべてのリクエストが「Task group is not initialized」で500を返します。set_read_only/set_autocommitは、接続に対するすべてのexecute()より前に実行されなければなりません。 そうしないと、プールは「connection in transaction status INTRANS」で失敗します。pg_class.reltuplesはビューには無意味です。そのため、行数の見積もりは起動時に上限付きのcount(*)にフォールバックします。Supavisorは
application_nameを「Supavisor」に書き換えます。そのため、プーラー経由でクライアントごとの接続を特定することはできません。MCP SDK 2.0は
FastMCPをMCPServerに改名し、mcp.server.fastmcpから移動させました。そのためrequirements.txtは完全なロックファイルになっています。
ライセンス
MIT — LICENSE を参照してください。
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables Claude to interact with PostgreSQL databases by executing SQL queries, exploring schemas, and monitoring database health. It provides tools for data manipulation and schema management via a secure SSE connection.287MIT
- FlicenseNot gradedqualityDmaintenanceEnables Claude Desktop to query a PostgreSQL brand database through MCP. Supports local stdio and remote HTTP/SSE deployments with API key authentication for secure database access.
- FlicenseNot gradedqualityDmaintenanceEnables natural language querying of PostgreSQL databases through the Model Context Protocol. It translates user questions into validated SQL, executes read-only queries safely, and returns results to MCP-compatible clients like Claude Desktop.
- AlicenseAqualityAmaintenanceQuery and manage PostgreSQL databases from Claude Code, Cursor, and any MCP client, with read-only by default and built-in schema introspection, EXPLAIN, and performance diagnostics.211,8093MIT
Related MCP Connectors
Analytical memory for AI agents: a real Postgres queried in plain English over MCP. One command.
Query PostgreSQL databases in plain English — LLM-generated, safety-validated SQL.
MCP server for managing Prisma Postgres.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Sa3fa/pg-analytics-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server