关于 warehouse-mcp
warehouse-mcp 是面向需要将 AI 客户端连接到数据仓库的团队的只读 MCP 服务,支持多种仓库适配器。它结合分级角色控制、审计、可选 PII 遮蔽和语义元数据。
主要功能
- 01只读查询与目录工具
- 02五级基于角色的访问控制
- 03可选仓库角色模拟
- 04JSONL 审计日志
- 05可选结果 PII 遮蔽
- 06语义元数据工具与资源
适用场景
- 01按角色限制分析人员查询数据
- 02浏览 Schema、表和列信息
- 03提供业务术语表及表格背景
- 04遮蔽查询结果中的敏感值
MCP 相关
该 MCP 服务向客户端提供只读查询、目录、数据剖析和语义元数据工具。语义元数据也可通过 warehouse://semantic/* 资源提供,并支持按会话控制可见性。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y warehouse-mcpMCP_TRANSPORTSet to 'stdio' for desktop AI clients (Claude Desktop, Cursor). Defaults to 'http'.WAREHOUSE_TYPEWhich warehouse to connect to. One of: postgres, oracle, redshift, snowflake, bigquery, duckdb. (DuckDB also handles MotherDuck via DUCKDB_PATH=md:<db>.)MCP_API_KEYS密钥Comma-separated bearer keys with role and optional warehouse-role impersonation: 'key1:reader,key2:admin', 'key3:reader:set_role=alice'. Leave empty for stdio (OS process boundary is the trust boundary). Required for HTTP.DUCKDB_PATHDuckDB file path, ':memory:', or 'md:<database>' for MotherDuck. Required when WAREHOUSE_TYPE=duckdb.MOTHERDUCK_TOKEN密钥MotherDuck service token. Required when DUCKDB_PATH starts with 'md:'.PG_HOSTPostgres host. Required when WAREHOUSE_TYPE=postgres. (Use REDSHIFT_HOST for Redshift.)PG_DATABASEPostgres database name.PG_USERPostgres user.PG_PASSWORD密钥Postgres password.ORACLE_USEROracle user. Required when WAREHOUSE_TYPE=oracle.ORACLE_PASSWORD密钥Oracle password.ORACLE_CONNECT_STRINGOracle Easy Connect (e.g. host:1521/SERVICE), TNS descriptor, or alias.SNOWFLAKE_ACCOUNTSnowflake account identifier (e.g. xy12345.us-east-1). Required when WAREHOUSE_TYPE=snowflake.SNOWFLAKE_USERSnowflake username.SNOWFLAKE_PRIVATE_KEY_PATH密钥Path to PKCS8 private key (.p8). Snowflake auth is key-pair only; password auth is not supported.BIGQUERY_PROJECTGCP project id. Required when WAREHOUSE_TYPE=bigquery.GOOGLE_APPLICATION_CREDENTIALS密钥Path to BigQuery service-account JSON. Omit on GKE / Cloud Run with workload identity.GUARDRAIL_PII_MASKSet to 'on' to enable role-aware PII masking on result rows (emails, SSNs, phones, IPs, Luhn-validated CCs). Off by default.MCP_RATE_LIMIT_RPMPer-principal token-bucket rate limit on tool invocations. 0 = disabled. Recommend 60 for production.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
warehouse-mcp
面向数据仓库的生产级 MCP(Model Context Protocol)服务。提供只读强制执行、五级基于角色的访问控制、可选的数据仓库角色模拟(用于原生 RLS / CLS)、JSONL 审计日志、可选的输出 PII 脱敏,以及可选的语义元数据层(术语表 + 表文档),并支持按会话切换。可自行托管 Docker 镜像、通过 npx 安装,或等待即将推出的托管云版本。
状态: v0.4.x — 已为 v1 支持的数据仓库列表做好生产部署准备。各版本的发布内容请参阅 CHANGELOG。
演示视频
支持的数据仓库
| 数据仓库 | 适配器文档 |
|---|---|
| Postgres 12+ | docs/adapters/postgres.md |
| Oracle 12c+(Thin 模式,无需 Instant Client) | docs/adapters/oracle.md |
| Amazon Redshift(集群 + Serverless) | docs/adapters/redshift.md |
| Snowflake(密钥对身份验证) | docs/adapters/snowflake.md |
| Google BigQuery | docs/adapters/bigquery.md |
DuckDB(本地文件或 :memory:) | docs/adapters/duckdb.md |
MotherDuck(云托管的 DuckDB,md: 路径) | docs/adapters/duckdb.md |
Databricks SQL 将很快跟进。
提供的工具(共 16 个,均为只读)
| 工具 | 用途 |
|---|---|
query | 执行 SELECT(通过验证器强制只读,并适配对应方言) |
list_schemas、list_tables、describe_table | 浏览目录 |
find_columns | 使用 LIKE 模式搜索数据仓库中的列名 |
get_foreign_keys | 查找已声明的 FK 关系,以便安全地联接 |
get_view_definition | 读取视图的 SQL 主体(业务逻辑所在之处) |
sample_table、count_rows | 查看数据,扫描前检查数据量 |
column_stats、top_values | 分析单个列 |
time_series | 按小时/天/周/月/季度/年分桶——在所有数据仓库中均使用正确的方言 |
search_value | 在表的文本列中查找指定字面值 |
glossary_lookup | 从语义层读取业务术语表条目(驻留内存,不访问数据仓库) |
schema_lookup | 读取架构级文档——用途、所有者、刷新信息、表列表 |
table_lookup | 读取单个表的完整语义文档——描述 + 列元数据 |
角色(五个等级)
| 角色 | 允许使用的工具 |
|---|---|
semantic_only | 仅限三个语义查找工具——无法访问数据仓库;与 semantic=on 搭配使用,可作为文档查看器角色 |
metadata_only | 可发现目录和进行语义查找——不会读取行数据 |
reader_restricted | 可使用聚合、抽样和时间序列——不能任意执行 SELECT |
reader | 增加 query 和 search_value(通用分析员等级) |
admin | 所有功能;ENABLE_WRITE_TOOLS 发布后还可使用未来的写入工具 |
通过 MCP_API_KEYS=key:role[:set_role=warehouse_role][:semantic=on|off] 为每个密钥分配角色。可选指令 set_role= 会在 Postgres/Redshift 上执行 SET ROLE,让数据仓库自身的 RLS / CLS / 脱敏策略按密钥强制执行访问控制——无需在 MCP 中重复配置策略。可选指令 semantic=on|off 会覆盖该密钥的 SEMANTIC_DEFAULT,控制会话是否能看到 warehouse://semantic/* 资源(参见 docs/semantic-metadata.md)。
对于已有多个数据库角色(finance、hr、payroll 等)且拥有众多用户的部署,请参见 docs/multi-role-deployment.md——其中介绍了如何将约 10 个数据库角色映射到 MCP 密钥、推荐的 <area> / <area>_restricted 模式,以及何时从静态密钥升级到 OIDC。
MCP 连接 JSON 示例(根据你的角色进行更改):
{ "mcpServers": { "warehouse-admin-semanticon": { "command": "npx", "args": [ "-y", "mcp-remote@latest", "http://localhost:3001/mcp", "--header", "Authorization: Bearer admin-key-change-me" ] }, "warehouse-admin-semanticoff": { "command": "npx", "args": [ "-y", "mcp-remote@latest", "http://localhost:3001/mcp", "--header", "Authorization: Bearer admin-key-nosemantic" ] }, "warehouse-reader-semanticon": { "command": "npx", "args": [ "-y", "mcp-remote@latest", "http://localhost:3001/mcp", "--header", "Authorization: Bearer reader-key-change-me" ] }, "warehouse-reader-semanticoff": { "command": "npx", "args": [ "-y", "mcp-remote@latest", "http://localhost:3001/mcp", "--header", "Authorization: Bearer reader-key-nosemantic" ] }, "warehouse-reader-restricted-semanticon": { "command": "npx", "args": [ "-y", "mcp-remote@latest", "http://localhost:3001/mcp", "--header", "Authorization: Bearer restricted-key-change-me" ] }, "warehouse-reader-restricted-semanticoff": { "command": "npx", "args": [ "-y", "mcp-remote@latest", "http://localhost:3001/mcp", "--header", "Authorization: Bearer restricted-key-nosemantic" ] }, "warehouse-metadata-only-semanticon": { "command": "npx", "args": [ "-y", "mcp-remote@latest", "http://localhost:3001/mcp", "--header", "Authorization: Bearer metadata-only-key-change-me" ] }, "warehouse-metadata-only-semanticoff": { "command": "npx", "args": [ "-y", "mcp-remote@latest", "http://localhost:3001/mcp", "--header", "Authorization: Bearer metadata-only-key-nosemantic" ] }, "warehouse-docs-viewer-only": { "command": "npx", "args": [ "-y", "mcp-remote@latest", "http://localhost:3001/mcp", "--header", "Authorization: Bearer docs_viewer_key_change_me" ] } } }
快速开始
选项 A — Docker compose(使用预置 Postgres 的 5 分钟演示)
git clone https://github.com/kalehdoo/warehouse-mcp.git
cd warehouse-mcp
docker compose up
# server on http://localhost:3001, seeded ecommerce data in Postgres
选项 B — 使用 Docker 连接自有数据仓库
同一个镜像打包了所有适配器;通过 WAREHOUSE_TYPE 和对应的凭据选择适配器。对于凭据,优先使用 --env-file(或你的密钥管理器),而不是内联的 -e 标志,以免密码进入 shell 历史记录。
# Postgres (REDSHIFT_* env vars for Redshift; same driver under the hood)
docker run -d -p 3001:3001 \
-e WAREHOUSE_TYPE=postgres \
-e PG_HOST=db -e PG_DATABASE=analytics -e PG_USER=mcp_reader -e PG_PASSWORD=... \
-e MCP_API_KEYS="$(openssl rand -hex 24):reader" \
ghcr.io/kalehdoo/warehouse-mcp:latest
# Oracle (Thin mode, no Instant Client)
docker run -d -p 3001:3001 \
-e WAREHOUSE_TYPE=oracle \
-e ORACLE_USER=MCP_READER -e ORACLE_PASSWORD=... \
-e ORACLE_CONNECT_STRING="db.host:1521/SERVICE" \
ghcr.io/kalehdoo/warehouse-mcp:latest
# Snowflake (key-pair, mount the .p8)
docker run -d -p 3001:3001 \
-e WAREHOUSE_TYPE=snowflake \
-e SNOWFLAKE_ACCOUNT=xy12345.us-east-1 -e SNOWFLAKE_USER=MCP_READER \
-e SNOWFLAKE_PRIVATE_KEY_PATH=/keys/snowflake.p8 \
-e SNOWFLAKE_WAREHOUSE=COMPUTE_WH -e SNOWFLAKE_DATABASE=ANALYTICS \
-v /opt/keys:/keys:ro \
ghcr.io/kalehdoo/warehouse-mcp:latest
# BigQuery (mount the service-account JSON)
docker run -d -p 3001:3001 \
-e WAREHOUSE_TYPE=bigquery \
-e GOOGLE_APPLICATION_CREDENTIALS=/keys/bq-sa.json \
-e BIGQUERY_PROJECT=my-gcp-project \
-v /opt/keys:/keys:ro \
ghcr.io/kalehdoo/warehouse-mcp:latest
# DuckDB (file or in-memory)
docker run -d -p 3001:3001 \
-e WAREHOUSE_TYPE=duckdb -e DUCKDB_PATH=:memory: \
ghcr.io/kalehdoo/warehouse-mcp:latest
# MotherDuck (hosted DuckDB)
docker run -d -p 3001:3001 \
-e WAREHOUSE_TYPE=duckdb -e DUCKDB_PATH=md:my_database \
-e MOTHERDUCK_TOKEN=... \
ghcr.io/kalehdoo/warehouse-mcp:latest
选项 C — 使用 npx(无需容器)
npx warehouse-mcp@latest init # interactive setup; writes .env, prints Claude Desktop snippet
npx warehouse-mcp doctor # verify the connection without booting the server
npx warehouse-mcp start # bind the MCP server to MCP_SERVER_PORT (default 3001)
然后让 AI 客户端连接到它。可直接使用的配置:
如需了解从“我有一个数据仓库”到“Claude 正在查询它”的分步指南,请参阅入门指南。如需查看常见错误,请参阅故障排除。
本地开发
nvm use # Node 20
npm install
npm test # unit tests, sub-second
npm run lint
cp .env.example .env
如需针对真实 Postgres 运行 testcontainers 集成测试:npm run test:integration(需要 Docker)。
环境设置
- MCP_API_KEYS
- WAREHOUSE_TYPE
- SEMANTIC_DIR
可选:语义元数据(v0.4+)
让 AI Agent 了解你的数据仓库意味着什么,而不只是了解其中有什么。将描述业务术语表和表语义的 YAML 文件放入某个目录,将 SEMANTIC_DIR 指向该目录,Agent 即可通过两个访问渠道,使用同一个内存索引:
- MCP 资源,位于
warehouse://semantic/*— 支持工具的客户端(Cursor、MCP Inspector)会在发出查询前主动读取这些资源。 - MCP 工具:
glossary_lookup、schema_lookup、table_lookup— 通过工具渠道访问相同的数据,适用于界面以工具为中心、可能会隐藏仅提供资源的服务的客户端(Claude Desktop)。纯内存Map.get— 不访问数据仓库,除常规工具日志行外不产生审计成本。
格式遵循 dbt 的 schema.yml v2,并扩展一项功能(每个模型使用 meta.schema:)。使用 dbt 的客户可以将 SEMANTIC_DIR 指向现有的 models/ 目录,重复利用其中大部分内容。请参阅 docs/semantic-metadata.md 和入门模板 docs/semantic-templates/。
按会话切换
会话是否能看到语义层,与是否加载 YAML 文件相互独立 — SEMANTIC_DIR 控制加载;SEMANTIC_DEFAULT=on|off 和每个密钥的 semantic=on|off 选项(或 include_semantic JWT 声明)控制每个会话的可见性。启动时始终会加载并验证 YAML 文件,因此无需重启即可切换紧急开关。优先级分为三层,从高到低:
- 每个 JWT 声明 —
include_semantic: true|false(OIDC)。 - 每个 API 密钥选项 —
MCP_API_KEYS中的semantic=on|off。 - 服务默认值 —
SEMANTIC_DEFAULT=on|off(默认为on)。
每条工具调用审计记录都会记录解析后的 include_semantic 值,便于事后将查询质量与语义信息的暴露情况关联起来。
可选:OpenTelemetry 跟踪
默认关闭。在环境变量中设置 OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318/v1/traces,服务就会为每次工具调用发出 span。资源属性:service.name=warehouse-mcp、service.version=<package.json version>。Span 属性:warehouse.tenant、warehouse.role。兼容任何 OTLP/HTTP 后端(Grafana Tempo、Honeycomb、Datadog APM、New Relic、SigNoz)。
可选:输出 PII 遮蔽
默认关闭。设置 GUARDRAIL_PII_MASK=on 后,服务会遮蔽结果行中的电子邮件地址、SSN、格式化电话号码、IPv4 地址以及通过 Luhn 算法验证的信用卡号。遮蔽级别取决于调用者的角色:admin 可查看原始值,reader 可查看部分遮蔽的值(a***@example.com),reader_restricted 可查看完全遮蔽的标签。
工作原理
阅读架构文档,了解请求流程:MCP 客户端发起调用时会执行哪些文件、护栏流水线如何围绕工具处理程序组合,以及添加新工具/护栏/适配器的操作指南。这是一份面向运维人员、安全审查人员和贡献者的单页指南。
安全
部署前请阅读威胁模型。其中介绍了 OWASP Top 10 映射、代码库会缓解哪些风险,以及部署时需要自行处理的事项(TLS、密钥管理、网络隔离、成本防护措施)。请按照 SECURITY.md 报告漏洞。
贡献
欢迎提交问题和 PR。请从 CONTRIBUTING.md 开始,其中介绍了开发工作流、适配器契约,以及如何添加新的仓库。参与贡献即表示你同意行为准则。
许可证
Apache-2.0
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。