Token导航 LogoToken导航TokenDH.com
Sanitized Db MCP logo
数据服务stdio官方级别未说明来源级核验

Sanitized Db MCP

MCP Server

一个通过AST级别重写SQL查询来防止PII/PHI暴露的MCP服务器,适用于AI代理与PostgreSQL数据库之间的安全查询处理。

工具数

1

提示词数

0

GitHub Stars

0

资源数

0
隐私保护PostgreSQLClaudeClaude

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

作者 / 组织

ruminaider

提供方

ruminaider

最后核验

2026/5/17 20:21

快速接入

先看主来源和安装命令,再打开仓库或文档;下面只保留这个条目的关键接入事实。

命令预览

pip install sanitized-db-mcp

详细介绍

山宁泰DB MCP服务器

![PyPI](https://pypi.org/project/sanitized-db-mcp/) ](https://ghcr.io/ruminaider/sanitized-db-mcp) ![Tests](https://github.com/ruminaider/sanitized-db-mcp/actions/workflows/test.yml)

在AST级别重写SQL查询以防止PII/PHI暴露的MCP服务器。

为什么存在

AI代理编写SQL。他们还会产生列名幻觉,忽略访问控制,并愉快地从充满个人数据的表中选择\*。该服务器位于代理和PostgreSQL数据库之间,重写每个查询,使隐藏列返回保留类型的占位符而不是真实值。该代理获得了有用的结果;你的用户会保护他们的隐私。

快速开始

1.创建一个满负荷列表

从数据库架构生成脚手架:

# Install the CLI (skip if using uvx or Docker below)
pip install sanitized-db-mcp

sanitized-db-mcp generate-allowlist --database-url postgresql://user:pass@host:5432/mydb > allowlist.yaml

编辑YAML以仅显示代理应该看到的列(请参见 生成允许列表 在......下面

2.运行服务器

从下面四种方法中选择一种,并将配置添加到您的 .mcp.json.

方法1:uvx(推荐——零安装)

uvx 在没有永久安装和依赖冲突的隔离环境中运行该包。与pip不同,它不需要安装或管理任何东西。与Docker不同,不需要配置卷挂载或路径映射。

{
  "sanitized-db": {
    "type": "stdio",
    "command": "uvx",
    "args": ["sanitized-db-mcp"],
    "env": {
      "ALLOWLIST_PATH": "./allowlist.yaml",
      "DATABASE_URL": "postgresql://user:pass@host:5432/mydb"
    }
  }
}

无需安装。 uvx 在隔离环境中下载并运行该包。

方法2:pip安装

pip install sanitized-db-mcp
{
  "sanitized-db": {
    "type": "stdio",
    "command": "python3",
    "args": ["-m", "sanitized_db_mcp.server"],
    "env": {
      "ALLOWLIST_PATH": "./allowlist.yaml",
      "DATABASE_URL": "postgresql://user:pass@host:5432/mydb"
    }
  }
}

方法3:Docker(预构建镜像)

{
  "sanitized-db": {
    "type": "stdio",
    "command": "docker",
    "args": [
      "run", "-i", "--rm",
      "-e", "ALLOWLIST_PATH=/app/allowlist.yaml",
      "-e", "DATABASE_URL",
      "-v", "./allowlist.yaml:/app/allowlist.yaml:ro",
      "ghcr.io/ruminaider/sanitized-db-mcp:latest"
    ],
    "env": {
      "DATABASE_URL": "postgresql://user:pass@host:5432/mydb"
    }
  }
}

方法4:Docker(从源代码构建)

docker build -t sanitized-db-mcp:local .
{
  "sanitized-db": {
    "type": "stdio",
    "command": "docker",
    "args": [
      "run", "-i", "--rm",
      "-e", "ALLOWLIST_PATH=/app/allowlist.yaml",
      "-e", "DATABASE_URL",
      "-v", "./allowlist.yaml:/app/allowlist.yaml:ro",
      "sanitized-db-mcp:local"
    ],
    "env": {
      "DATABASE_URL": "postgresql://user:pass@host:5432/mydb"
    }
  }
}

3.通过代理查询

服务器公开了一个MCP工具(query)它接受原始SQL并返回经过净化的结果。

生成允许列表

CLI工具连接到数据库,读取模式,并生成一个YAML文件,其中 默认情况下不可见。您可以通过取消注释来选择列。

sanitized-db-mcp generate-allowlist --database-url postgresql://user:pass@host:5432/mydb > allowlist.yaml

添加 --deny-pii 标记看起来像PII(电子邮件、姓名、电话、地址等)的列:

sanitized-db-mcp generate-allowlist --database-url postgresql://... --deny-pii > allowlist.yaml

输出示例:

# Generated by: sanitized-db-mcp generate-allowlist --deny-pii
#
# HOW TO USE:
# - Columns under "columns:" are VISIBLE to agents (currently empty)
# - Commented lines show available columns — uncomment to make visible
# - Lines marked "# PII" were flagged as likely PII/PHI — review carefully
# - After editing, restart the MCP server to apply changes

tables:
  users:
    columns: {}
    # Available columns (uncomment to make visible):
    #   id: {type: integer, placeholder: 0}
    #   is_active: {type: boolean, placeholder: false}
    #   email: {type: varchar, placeholder: '[REDACTED]'}  # PII
    #   password: {type: varchar, placeholder: '[REDACTED]'}  # PII

取消注释您希望代理看到的列。把其他东西都藏起来。

允许列表YAML格式

tables:
  :
    columns:
      : {type: 
, placeholder: }
allowed_functions:
  - FUNCTION_NAME
  • 列出的列是可见的。 未列出的列将被隐藏,并替换为保留类型的占位符。
  • type:基本PostgreSQL类型(integer, varchar, boolean, timestamp, uuid, jsonb等等)。
  • placeholder:替换隐藏列值的SQL文字。必须与类型兼容。
  • allowed_functions:代理可以调用的SQL函数。其他人都被拒绝了。

配置

变量必填默认描述
ALLOWLIST_PATH--路径 allowlist.yaml
MCP_SERVER_NAME没有sanitized-dbMCP服务器名称(影响工具名称: mcp____query)
DATABASE_URL如果不使用Render--PostgreSQL连接字符串
RENDER_POSTGRES_ID如果使用Render--渲染Postgres实例ID
RENDER_API_KEY如果使用Render--Render API承载令牌

如果同时设置了“渲染API”凭据,则服务器会首选这两个凭据。为了地方发展, DATABASE_URL 足够了。

框架集成

  • 姜戈:使用a visible() 字段装饰器标记安全字段,然后从模型元数据生成分配列表。
  • 轨道/其他:使用CLI工具搭建脚手架,然后手动管理。或者构建自己的生成器,输出相同的YAML格式。
  • 自定义生成器:YAML格式是合约。任何生成符合要求的YAML的工具都可以使用。

SSE传输(远程部署)

对于共享部署(例如Render.com),服务器支持通过HTTP的SSE传输。

安装

pip install 'sanitized-db-mcp[sse]'

配置

变量必填默认描述
MCP_TRANSPORT没有stdio运输方式: stdiosse
PORT没有8000HTTP端口(渲染会自动设置此端口)
MCP_API_KEY推荐--HTTP身份验证的承载令牌
MCP_MAX_CONNECTIONS无限制最大并发连接数(uvicon limit_concurrency)
MCP_SESSION_TIMEOUT无限制最大SSE会话持续时间(秒)

跑步

export MCP_TRANSPORT=sse
export MCP_API_KEY=your-secret-key
export ALLOWLIST_PATH=./allowlist.yaml
export DATABASE_URL=postgresql://...
python -m sanitized_db_mcp.server

码头工人

docker run -e MCP_TRANSPORT=sse -e MCP_API_KEY=secret -e ALLOWLIST_PATH=/app/allowlist.yaml \
  -e DATABASE_URL=postgresql://... -p 8000:8000 sanitized-db-mcp

Claude代码客户端配置

在MCP客户端配置中,指向SSE端点:

{
  "mcpServers": {
    "sanitized-db": {
      "type": "sse",
      "url": "https://your-service.onrender.com/sse",
      "headers": {
        "Authorization": "Bearer your-secret-key"
      }
    }
  }
}

端点

  • GET /sse --SSE连接(MCP会话)
  • POST /messages/ --客户端到服务器消息
  • GET /health --健康检查(无需身份验证)

部署指南

连接限制:MCP_MAX_CONNECTIONS 以防止在攻击或配置错误的情况下资源耗尽。一个合理的值是预期并发客户端的2-5x(例如,当预期10-20个客户端时为100)。超出限制的新连接将接收HTTP 503。注:每个SSE会话和每个 /messages/ 来自该会话的POST计数为单独的并发连接,因此不要将其设置得太低。

会话超时:MCP_SESSION_TIMEOUT (秒)关闭废弃的SSE会话。28800(8小时)是一个合理的起点。客户端在超时后自动重新连接。如果没有这一点,自uvicorn以来,被放弃的会话会无限期地消耗资源 timeout_keep_alive 不适用于活动的SSE流。

CORS: CORS标头被有意省略。服务器的客户端(Claude Code、MCP CLI工具)是忽略CORS的非浏览器应用程序。原生浏览器 EventSource API无法发送 Authorization 头文件,因此浏览器即使尝试跨源连接也无法进行身份验证。如果基于浏览器的MCP客户端成为受支持的消费者,请添加Starlette的 CORSMiddleware.

审核日志记录: 每个查询都以结构化JSON的形式记录,其中包含客户端IP、请求ID、会话ID和用户代理,以符合HIPAA标准。在反向代理(Render、nginx)后面,从中提取客户端IP X-Forwarded-For。根据HIPAA要求,配置日志聚合器以保留6年。

消毒剂的工作原理

服务器公开了一个MCP工具(query)它接受原始SQL并返回经过净化的结果。每个查询都要经过一个11步的管道:

Agent sends SQL
      |
      v
1.  Parse (pglast) ───── syntax error? → QuerySyntaxError
      |
      v
2.  Statement type ───── not SELECT? → StatementTypeError
      |                   SELECT INTO? → StatementTypeError
      |                   FOR UPDATE/SHARE? → StatementTypeError
      v
3.  Table validation ─── system catalog? → SystemCatalogError
      |                   not in allowlist? → RestrictedColumnError
      |                   TABLESAMPLE? → unwrap, validate inner table
      v
4.  Function check ───── always-blocked? → DisallowedFunctionError
      |                   not in allowlist? → DisallowedFunctionError
      |                   FILTER (WHERE ...)? → walk with WHERE rules
      |                   inline OVER clause? → walk with WHERE rules
      v
5.  WHERE/JOIN check ─── hidden column? → RestrictedColumnError
      v
6.  Clause check ──────── ORDER BY / GROUP BY / DISTINCT ON / WINDOW
      |                    hidden column? → RestrictedColumnError
      v
7.  Subquery check ───── hidden column in subquery/CTE SELECT? → RestrictedColumnError
      v
8.  Rewrite SELECT ───── hidden columns → type-preserving placeholders
      |                   SELECT * → visible columns + redaction marker
      v
9.  Serialize AST ────── rewritten SQL string
      v
10. Execute ───────────── read-only, 5s timeout, SSL
      v
11. Audit log ─────────── structured JSON (original, rewritten, outcome)

安全模型

所有200个测试均通过,0次失败。笔测试套件涵盖21种攻击类别:

类别测试防御
ORDER BY/GROUP BY/DISTINCT ON13sort子句、GROUP子句、DISTINCT子句与WHERE规则一起走
窗口函数攻击6命名为Window并内联OVER,遵循WHERE规则
聚合过滤器子句4agg_FILTER与WHERE规则一起运行
CTE攻击6CTE SELECT目标已验证;未使用的隐藏列CTE被拒绝
LATERAL连接攻击3相关子查询WHERE子句已验证
模式/标识符技巧8引用标识符、unicode转义、处理pg_temp模式
复合类型/行攻击3字段选择被拒绝;ROW(),隐藏列已编辑
ARRAY攻击3ARRAY子查询、ARRAY_AGG、ARRAY\[\]已捕获隐藏列
JSONB运算符攻击5->、->>、#>、@>、?已捕获隐藏列上的运算符
类型转换攻击4隐藏列上的链式转换已被编辑;在WHERE中铸造被拒绝
FROM子句变体3TABLESAMPLE展开,处理VALUES和generate_series
锁定子句3用于更新,用于共享,在消毒剂级别被拒绝
子查询嵌套5三重嵌套、相关、不存在、任何均已验证
语句类型/多语句5SELECT INTO被拒绝;空字节、注释、美元报价已测试
列解析不明确3保守地解决不合格列
编码边缘大小写4西里尔字母同形符、unicode转义符、别名中的分号
定时/侧通道4pg_sleep、放大、交叉连接、递归CTE被阻止
基于错误的提取4通用错误消息;没有泄漏列名/表名
连接安全5SSL、超时、只读、自动提交、无错误连接字符串
允许列表完整性4不区分大小写的查找,未知列默认为隐藏
审计日志4涵盖所有结果,HIPAA字段存在,最终阻止保证

运行测试

cd sanitized-db-mcp

# Full test suite (200 tests across 3 suites)
python -m pytest sanitized_db_mcp/tests/ -v

# Individual suites
python -m pytest sanitized_db_mcp/tests/test_sanitizer.py -v    # Core rewriting (37 tests)
python -m pytest sanitized_db_mcp/tests/test_bypass.py -v       # Bypass resistance (64 tests)
python -m pytest sanitized_db_mcp/tests/test_pentest.py -v      # Pen test (99 tests)
python -m pytest sanitized_db_mcp/tests/test_allowlist.py -v    # Allowlist loader

关键文件

文件目的
server.pyMCP服务器入口点, query(sql) 工具
sanitizer.pyAST级SQL重写引擎
allowlist.py记忆中的异体表示
connection.py呈现API+静态连接管理
errors.py山宁泰错误类(无模式泄漏)
audit.py符合HIPAA标准的查询审核日志记录

目录标签

目录标签

隐私保护PostgreSQLClaude数据库安全Python混合部署AI查询处理SQL重写

支持客户端

Claude

接入字段

传输方式(transport,传输协议)

stdio

鉴权方式(authType,认证方式)

token

工具数量(toolCount,工具数)

1

资源数量(resourceCount,资源数)

0

提示词数量(promptCount,提示词数)

0

权限和风险

stdiotoken部署方式未说明

接入前请确认传输方式、认证方式和部署位置,并根据实际工具能力限制访问范围。

安装前确认

不要直接授予不必要的文件、网络或账号权限;先核对安装命令和配置内容。

来源信息

继续浏览同类 MCP