Skip to main content
Glama
Sa3fa

pg-analytics-mcp

by Sa3fa

pg-analytics-mcp

Ein konfigurationsgesteuerter, schreibgeschützter Postgres-MCP-Server für Claude. Stellen Sie ein Postgres-Schema über Streamable HTTP für Claude bereit, wobei Schema- und Enum-Werte beim Start aus der Live-Datenbank introspiziert werden und alles Clientspezifische in einer einzigen YAML-Datei liegt.

Entworfen für den Betrieb hinter Cloudflare Access auf einem cloudflared → Reverse-Proxy-Stack (ein vollständiges Provisioning-Playbook ist enthalten), aber der Server selbst hat keine Cloudflare-Abhängigkeit und läuft überall.

Client-agnostisch. Nichts unter server/ weiß von einem bestimmten Client. Um einen neuen zu bedienen: Repo kopieren, Konfigurationsdatei schreiben, .env setzen.

Warum es das gibt

Der Vorgänger stapelte drei Prozesse, um ein Anbieterpaket zu umgehen:

supergateway  →  enrich.py  →  postgres-mcp  →  Postgres

postgres-mcp spricht nur stdio/SSE (Cloudflare erfordert Streamable HTTP), hat überhaupt keine Konfigurationsoberfläche, und supergateway forkte ein Kind pro MCP-Sitzung, das nie beendet wurde – gemessen 23 Kinder / 15 Verbindungen gegen ein Rollenlimit von 20, was sich als „funktioniert für ~9 Aufrufe, dann schlägt alles fehl, einschließlich SELECT 1“ äußerte.

Dieser Server ist ein Prozess mit einem gemeinsamen Pool. Gemessen: 1 Prozess nach 30 Tool-Aufrufen.

Related MCP server: Brand MCP Server

Architektur

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

Die Sicherheitsgrenze ist die Datenbankrolle, nicht dieser Server.

Schnellstart

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 boot

Folgen Sie dann docs/PLAYBOOK-NEW-CLIENT.md für die Cloudflare-Seite.

Konfiguration

.env – hostspezifisch, das Einzige, was sich zwischen VPS ändert:

Variable

Zweck

DATABASE_URI

Schreibgeschützte Rolle. Beim Supavisor-Pooler muss der Benutzername unbedingt .PROJECT_REF enthalten.

MCP_CONTAINER_NAME

Container, Image-Tag und Traefik-Router-Name

MCP_HOSTNAME

Öffentlicher Hostname; wird automatisch zur Transport-Sicherheits-Allowlist hinzugefügt

TRAEFIK_NETWORK

Externes Docker-Netzwerk, das Traefik überwacht

MCP_CONFIG

Pfad zur Client-YAML im Image

MCP_LOCAL_PORT

Hostseitiger Veröffentlichungsport (Standard 8000)

config/<client>.yaml – die Domäne. Listen Sie hier keine Spalten oder Enum-Werte auf: Sie werden beim Start aus der Live-Datenbank introspiziert, können also nicht veralten. Schreiben Sie nur, was die Introspection nicht wissen kann – geschäftliche Bedeutung und Fallstricke.

Werkzeuge

Eingebaut:

  • execute_sql(sql) – rohes schreibgeschütztes SQL. Seine Beschreibung wird beim Start aus Ihrem verfassten Prosa plus den generierten Schema- und Enum-Listen zusammengesetzt.

  • list_views() – jedes lesbare Objekt mit Spalten, Zeilenzahlen, Enums.

  • describe_view(name) – Spalten eines Objekts.

Konfigurationsdefiniert: Jeder Eintrag unter tools.queries wird zu einem echten MCP-Tool mit typisierten Parametern. Parameter binden über psycopg benannte Platzhalter – niemals String-Interpolation – und min/max werden vor dem Binden erzwungen.

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)

Das ist der Teil, der die Lücke zu n8n schließt: Ein Tool hinzuzufügen ist Prosa + SQL, nicht Python.

Warum Beschreibungen hier leben

Tool-Beschreibungen sind der eine Kontext, den ein Modell immer dann sieht, wenn das Tool verfügbar ist – jeder Client, jedes Gespräch, kein Skill-Laden und keine Projektanweisungen. Domänenwissen, das in einem externen Dokument aufbewahrt wird, ist Wissen, das das Modell oft nicht hat.

Die Hälfte jeder Beschreibung ist verfasst (Urteil), die Hälfte generiert (Fakten). Die generierte Hälfte ist der Grund, warum die boxy-Plattform/Prozessor und die daily-Frequenz nicht mehr so fehlen können, wie sie es in dem handgeschriebenen Prompt taten, der diesem vorausging.

Betrieb

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

Eine Konfigurations- oder Schemaänderung erfordert einen Neustart – die Introspection wird für die Prozesslebensdauer bewusst gecacht, damit sich das Verhalten während des Laufs nicht ändern kann.

Die fünf Grenztests

Nach jeder Änderung an Views, Grants oder Konfiguration erneut ausführen. Alle fünf müssen fehlschlagen:

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 exist

limits.select_only existiert, ist aber standardmäßig aus: Die Rolle ist die Grenze, und ein SQL-Validator darüber blockiert gültige schreibgeschützte Konstrukte ohne Nutzen – deshalb wurde der eingeschränkte Modus von postgres-mcp aufgegeben.

Mit Blut bezahlte Fallstricke

  • Compose-Label-Schlüssel werden nicht variabel substituiert. Labels müssen in Listenform vorliegen (- "traefik...=value"), sonst erhalten Sie einen Router, der buchstäblich ${MCP_CONTAINER_NAME} heißt, und Traefik 404s.

  • DNS-Rebinding-Schutz ist standardmäßig aktiviert im MCP SDK. Der weitergeleitete Host hinter einem Proxy muss erlaubt sein; MCP_HOSTNAME und MCP_LOCAL_PORT werden automatisch hinzugefügt.

  • Das Mounten der MCP-App unter Ihrem eigenen Starlette ersetzt dessen Lebensdauer. Der Sitzungsmanager muss explizit gestartet werden (server.session_manager.run()), sonst antwortet jede Anfrage mit 500 und „Task group is not initialized“.

  • set_read_only / set_autocommit müssen jedem execute() auf einer Verbindung vorausgehen, sonst schlägt der Pool mit „connection in transaction status INTRANS“ fehl.

  • pg_class.reltuples ist für Views bedeutungslos, daher fallen Zeilenschätzungen beim Start auf ein begrenztes count(*) zurück.

  • Supavisor schreibt application_name zu „Supavisor“ um, daher ist eine pro-Client-Verbindungszuordnung durch den Pooler nicht möglich.

  • MCP SDK 2.0 hat FastMCP in MCPServer umbenannt und es aus mcp.server.fastmcp verschoben. requirements.txt ist aus diesem Grund ein vollständiger Lock.

Lizenz

MIT – siehe LICENSE.

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables 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.
    287
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables 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.
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables 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.
  • A
    license
    A
    quality
    A
    maintenance
    Query 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.
    21
    1,809
    3
    MIT

View all related MCP servers

Related MCP Connectors

View all MCP Connectors

Latest Blog Posts

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