Skip to main content

PostgreSQL Model Context Protocol (MCP) server

Project description

PostgreSQL MCP Server

Python 3.10+ License: MIT uv MCP

一个面向 PostgreSQL 的 Model Context Protocol (MCP) 服务。它基于 FastMCP 和 psycopg 构建,通过环境变量连接 PostgreSQL server,并以 database + schema 双层白名单 控制 MCP 客户端可以访问的范围。

PostgreSQL 的访问层级是:

PostgreSQL server / cluster
└── database
    └── schema
        └── table / view / index / function ...

因此本服务的当前上下文也是:

current_database + current_schema

切换 database 时会重新建立连接;切换 schema 时会在当前 database 内设置 search_path

功能特性

  • 🚀 面向 PostgreSQL server 的多 database 访问:允许在配置白名单内切换 database。
  • 🗂️ database + schema 双层白名单:每个 database 都有独立的 schema 白名单。
  • 🔐 安全的 search_path 设置:使用 psycopg 的 Identifier 处理 schema 名,避免手写拼接风险。
  • 🧰 清晰的 MCP 工具前缀:所有工具均以 pg_ 开头,便于和其他 MCP 服务共存。
  • 👁️ 只读模式:设置 POSTGRES_READ_ONLY=true 后,仅允许 SELECTWITHEXPLAINSHOW
  • 🛡️ SQL 安全审计:阻止多语句、注释注入、跨 schema 访问、权限变更、函数/过程/触发器/扩展等高风险操作。
  • 📚 常用元数据工具:支持列出 database、schema、表,描述表结构,统计表数量。
  • 📄 分页查询pg_execute_sqlSELECT/WITH 支持 limitoffset

工具列表

工具 说明
pg_test_connection 测试当前 database + schema 上下文是否可连接。
pg_get_current_context 返回当前 database、schema、允许的 database、当前 database 下允许的 schema。
pg_list_databases 列出配置允许访问的 database,并标记当前 database。
pg_switch_database 切换当前 database,可选同时切换目标 database 下的 schema。
pg_list_schemas 列出指定 database 或当前 database 中可见的非系统 schema。
pg_switch_schema 在当前 database 内切换当前 schema。
pg_execute_sql 在当前上下文执行 SQL。查询返回 datacount,写入返回 affected_rows
pg_list_tables 列出指定 database/schema 或当前上下文下的表和视图。
pg_describe_table 返回指定表的字段、数据类型、是否可空、默认值、主键标记。
pg_count_tables 统计指定 database/schema 或当前上下文下的普通表数量。

安装

推荐使用 uv

uv sync

运行服务:

uv run postgresql-mcp-server

环境变量

变量名 说明 必填 示例
POSTGRES_HOST PostgreSQL 主机地址 127.0.0.1
POSTGRES_PORT PostgreSQL 端口 5432
POSTGRES_USER PostgreSQL 用户名 postgres
POSTGRES_PASSWORD PostgreSQL 密码 your_password
POSTGRES_DEFAULT_DATABASE 启动后的默认 database appdb
POSTGRES_DEFAULT_SCHEMA 默认 database 下的默认 schema app
POSTGRES_ALLOWED_DATABASES 允许访问的 database,多个值用英文逗号分隔 appdb,reportdb
POSTGRES_DATABASE_SCHEMAS 每个 database 允许访问的 schema 映射 appdb:app,public;reportdb:reporting,analytics
POSTGRES_DATABASE_DEFAULT_SCHEMAS 每个 database 的默认 schema 映射 appdb:app;reportdb:reporting
POSTGRES_READ_ONLY 是否开启只读模式 false
POSTGRES_LOG_LEVEL 日志级别 INFO

不再使用旧的 POSTGRES_DATABASEPOSTGRES_SCHEMAPOSTGRES_ALLOWED_SCHEMAS 配置。

快速开始

单 database 配置

只允许访问 appdbapppublic 两个 schema:

$env:POSTGRES_HOST="127.0.0.1"
$env:POSTGRES_PORT="5432"
$env:POSTGRES_USER="postgres"
$env:POSTGRES_PASSWORD="your_password"
$env:POSTGRES_DEFAULT_DATABASE="appdb"
$env:POSTGRES_DEFAULT_SCHEMA="app"
$env:POSTGRES_ALLOWED_DATABASES="appdb"
$env:POSTGRES_DATABASE_SCHEMAS="appdb:app,public"
$env:POSTGRES_READ_ONLY="false"
uv run postgresql-mcp-server

多数据库、多 Schema 配置

允许访问多个 database,并为每个 database 分别配置可访问的 schema 白名单:

$env:POSTGRES_HOST="127.0.0.1"
$env:POSTGRES_PORT="5432"
$env:POSTGRES_USER="postgres"
$env:POSTGRES_PASSWORD="your_password"
$env:POSTGRES_DEFAULT_DATABASE="appdb"
$env:POSTGRES_DEFAULT_SCHEMA="app"
$env:POSTGRES_ALLOWED_DATABASES="appdb,reportdb,auditdb"
$env:POSTGRES_DATABASE_SCHEMAS="appdb:app,public;reportdb:reporting,analytics;auditdb:audit,archive"
$env:POSTGRES_DATABASE_DEFAULT_SCHEMAS="appdb:app;reportdb:reporting;auditdb:audit"
$env:POSTGRES_READ_ONLY="false"
uv run postgresql-mcp-server

上面的配置表示:

appdb
  default schema: app
  allowed schemas: app, public

reportdb
  default schema: reporting
  allowed schemas: reporting, analytics

auditdb
  default schema: audit
  allowed schemas: audit, archive

配置规则:

  • POSTGRES_ALLOWED_DATABASES 控制允许访问哪些 database。
  • POSTGRES_DATABASE_SCHEMAS 控制每个 database 下允许访问哪些 schema,格式为 database:schema1,schema2;database2:schema3,schema4
  • POSTGRES_DATABASE_DEFAULT_SCHEMAS 控制切换到某个 database 时默认使用哪个 schema。
  • POSTGRES_DEFAULT_DATABASEPOSTGRES_DEFAULT_SCHEMA 是服务启动后的初始上下文,必须在对应白名单中。

只读模式

$env:POSTGRES_READ_ONLY="true"
uv run postgresql-mcp-server

只读模式开启后,pg_execute_sql 仅允许 SELECTWITHEXPLAINSHOW 开头的语句。

MCP 客户端配置

uvx 配置

适合包发布后使用:

{
  "mcpServers": {
    "postgresql_mcp_server": {
      "command": "uvx",
      "args": ["postgresql-mcp-server@latest"],
      "env": {
        "POSTGRES_HOST": "127.0.0.1",
        "POSTGRES_PORT": "5432",
        "POSTGRES_USER": "postgres",
        "POSTGRES_PASSWORD": "your_password",
        "POSTGRES_DEFAULT_DATABASE": "appdb",
        "POSTGRES_DEFAULT_SCHEMA": "app",
        "POSTGRES_ALLOWED_DATABASES": "appdb,reportdb",
        "POSTGRES_DATABASE_SCHEMAS": "appdb:app,public;reportdb:reporting,analytics",
        "POSTGRES_DATABASE_DEFAULT_SCHEMAS": "appdb:app;reportdb:reporting",
        "POSTGRES_READ_ONLY": "false",
        "POSTGRES_LOG_LEVEL": "INFO"
      }
    }
  }
}

多数据库、多 Schema 客户端配置

下面示例允许 MCP 客户端在 appdbreportdbauditdb 三个 database 间切换,并分别限制每个 database 可访问的 schema:

{
  "mcpServers": {
    "postgresql_mcp_server": {
      "command": "uvx",
      "args": ["postgresql-mcp-server@latest"],
      "env": {
        "POSTGRES_HOST": "127.0.0.1",
        "POSTGRES_PORT": "5432",
        "POSTGRES_USER": "postgres",
        "POSTGRES_PASSWORD": "your_password",
        "POSTGRES_DEFAULT_DATABASE": "appdb",
        "POSTGRES_DEFAULT_SCHEMA": "app",
        "POSTGRES_ALLOWED_DATABASES": "appdb,reportdb,auditdb",
        "POSTGRES_DATABASE_SCHEMAS": "appdb:app,public;reportdb:reporting,analytics;auditdb:audit,archive",
        "POSTGRES_DATABASE_DEFAULT_SCHEMAS": "appdb:app;reportdb:reporting;auditdb:audit",
        "POSTGRES_READ_ONLY": "false",
        "POSTGRES_LOG_LEVEL": "INFO"
      }
    }
  }
}

使用该配置时,pg_switch_database 只能切换到 appdbreportdbauditdbpg_switch_schema 只能在当前 database 对应的 schema 白名单内切换。

本地开发配置

如果还没有发布到 PyPI,可以让 MCP 客户端在项目目录中通过 uv run 启动:

{
  "mcpServers": {
    "postgresql_mcp_server": {
      "command": "uv",
      "args": ["run", "postgresql-mcp-server"],
      "cwd": "E:/PycharmProjects/postgresql-mcp-server",
      "env": {
        "POSTGRES_HOST": "127.0.0.1",
        "POSTGRES_PORT": "5432",
        "POSTGRES_USER": "postgres",
        "POSTGRES_PASSWORD": "your_password",
        "POSTGRES_DEFAULT_DATABASE": "appdb",
        "POSTGRES_DEFAULT_SCHEMA": "app",
        "POSTGRES_ALLOWED_DATABASES": "appdb,reportdb",
        "POSTGRES_DATABASE_SCHEMAS": "appdb:app,public;reportdb:reporting,analytics"
      }
    }
  }
}

不同 MCP 客户端对 cwd 字段的支持可能不同;如果客户端不支持 cwd,请把命令改成在项目目录中执行的绝对路径包装脚本,或使用已发布的 uvx postgresql-mcp-server 方式。

使用示例

查看当前上下文:

{}

切换到 reportdb 的默认 schema:

{
  "database": "reportdb"
}

切换到 reportdb.analytics

{
  "database": "reportdb",
  "schema": "analytics"
}

查询并分页:

{
  "sql": "SELECT id, name FROM users ORDER BY id",
  "fetch_results": true,
  "limit": 20,
  "offset": 0
}

描述指定上下文中的表:

{
  "database": "reportdb",
  "schema": "analytics",
  "table": "daily_metrics"
}

安全策略

这个服务的安全策略用于降低 MCP 自动化场景中的误操作风险,但不能替代数据库侧权限控制。生产环境建议使用最小权限账号,并只开放必要 database 和 schema。

服务会在执行 SQL 前进行以下审计:

  • 禁止多语句执行,例如 SELECT ...; DROP TABLE ...
  • 禁止 SQL 注释,降低注释截断和注入风险。
  • 禁止 CALLDOEXECGRANTREVOKE 等高风险语句。
  • 只允许表和索引类 DDL,例如 CREATE TABLEALTER TABLEDROP INDEX
  • 禁止角色、用户、数据库、扩展、函数、过程、触发器、策略等对象的 DDL。
  • 禁止访问当前 database 白名单之外的 schema.objectschema.table.column
  • 允许查询中的别名、CTE、子查询和表名作为列限定符,例如 u.idorders.id
  • 对三段式标识符只把第一段识别为 schema,例如 app.users.id 只校验 app 是否在当前 database 的 schema 白名单中,不会把 users.id 再误判为跨 schema 访问。
  • 允许访问 PostgreSQL 系统 schema 的只读元数据,例如 information_schemapg_catalog

PostgreSQL 原生连接不能直接跨 database 查询。本服务不会伪装支持跨 database SQL;如果需要跨 database 汇总,请分别切换 database 查询,或在数据库侧配置 postgres_fdw / dblink

开发与测试

同步依赖:

uv sync

运行单元测试:

uv run python -m unittest

语法检查:

uv run python -m py_compile postgresql_mcp_server.py

当前测试覆盖 SQL 安全审计、database/schema 白名单、database 切换、schema 切换、分页包装和 fake connection 执行顺序。

常见问题

为什么要同时配置 database 和 schema?

PostgreSQL 的 database 与 schema 是不同层级。客户端连接时必须连接某个 database;表和视图通常属于该 database 下的某个 schema。

切换 database 和切换 schema 有什么区别?

切换 database 会重新建立连接;切换 schema 只是在当前 database 内调整 search_path

可以直接执行跨 database SQL 吗?

不可以。PostgreSQL 单个连接不能直接跨 database 查询。请使用 MCP 工具分别切换 database 查询,或在数据库侧配置 postgres_fdw / dblink

这个服务可以替代数据库权限控制吗?

不可以。MCP 层的安全审计是额外保护,数据库账号仍应遵循最小权限原则。

License

MIT License. See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

postgresql_mcp_server-1.1.0.tar.gz (18.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

postgresql_mcp_server-1.1.0-py3-none-any.whl (16.3 kB view details)

Uploaded Python 3

File details

Details for the file postgresql_mcp_server-1.1.0.tar.gz.

File metadata

  • Download URL: postgresql_mcp_server-1.1.0.tar.gz
  • Upload date:
  • Size: 18.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.11 {"installer":{"name":"uv","version":"0.9.11"},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for postgresql_mcp_server-1.1.0.tar.gz
Algorithm Hash digest
SHA256 6332eb69acbe0be3db3302b2b12368d2ba38a13a7a55b0c977b93904203b5c31
MD5 a1fbedcad013f8e66dc7e86e4f5079dc
BLAKE2b-256 de530e3198c81d37149da7c0e3f5b16f1d7f70457b1e325a21e2987959ee0cf8

See more details on using hashes here.

File details

Details for the file postgresql_mcp_server-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: postgresql_mcp_server-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 16.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.11 {"installer":{"name":"uv","version":"0.9.11"},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for postgresql_mcp_server-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9e6d192ea9abe1cbebce0e199989e4121fa3d60bc2a99d881a067f9fc2d83056
MD5 3684a4e6b42fca5ce67f3a5bcd9a739c
BLAKE2b-256 795f488ee49986d5cb265722817ed7753ff02c3d57a62775551f23bcf861f851

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page