关于 Warehouse Context
Warehouse Context 是一款 MCP 服务,为分析和编码 Agent 提供受治理的数据仓库文档、血缘、时效信息及受限查询方式。它支持 DuckDB、Snowflake 和 Databricks,并以只读 SELECT、行数限制和个人信息保护约束查询。
主要功能
- 01列出并描述已记录的数据表
- 02追踪上游来源和下游使用方
- 03按预期检查数据表时效
- 04查看已屏蔽个人信息的样例行
- 05执行受限制的只读 SELECT 查询
- 06支持 DuckDB、Snowflake 和 Databricks
适用场景
- 01查找分析指标的受治理数据源
- 02检查数据表是否符合时效要求
- 03查看样例行而不暴露个人信息
- 04在只读限制下查询仓库数据
MCP 相关
MCP 服务提供六种只读工具,用于发现数据表、查看描述和血缘、检查时效、读取脱敏样例及执行受限制的 SQL 查询。支持 stdio 和 Streamable HTTP 传输。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
6收录的工具列表 · 更新于 4 天前
此工具无需参数。
详细介绍
warehouse-context-mcp
一个 MCP 服务,为 AI Agent 提供可信且受治理的数据仓库上下文:每张表的含义、来源、数据新鲜度,以及一种无法写入、无法失控运行、也无法泄露个人数据的查询方式。
编码和分析 Agent 擅长编写 SQL,却不擅长判断该信任哪张表。仅凭架构信息,它们无法知道 fct_voyage_economics 是计算 TCE 的受治理数据源、stg_voyages 是暂存表、contact_email 属于个人数据,也无法知道某张表已经两天没有更新。这个服务让 Agent 只需调用一次工具即可获取这些上下文,并为其他操作设置防护措施。
工具
| 工具 | Agent 可获取的信息 |
|---|---|
list_tables | 每张表及其文档记录的用途和负责人 |
describe_table | 列、类型、说明、PII 标记、粒度、行数、未记录的列 |
table_lineage | 上游来源和下游使用者,避免循环并限制深度 |
table_freshness | 最近更新时间、数据年龄,以及是否符合文档记录的预期 |
sample_rows | 若干示例行,PII 已脱敏 |
run_query | 一条只读 SELECT 查询,限制返回行数,并保护 PII |
后端
| 后端 | 状态 | 读取的原生上下文 | 只读连接层 |
|---|---|---|---|
| DuckDB | v0.1 | 无(仅 YAML 目录) | 以 read_only 模式打开文件 |
| Snowflake | v0.2 | 表和列注释、pii 对象标签 | 仅允许 SELECT 的角色(演示脚本中的 WCM_READER) |
| Databricks | v0.2 | Unity Catalog 注释、pii 列标签 | 仅获得 USE 和 SELECT 授权的主体 |
数据仓库中存储的注释和标签会与经过整理的 YAML 目录合并:经过整理的值优先,原生值用于补充缺失信息,任一来源标记的 PII 标记都会保留。
防护措施
Agent 发送的每条查询都视为攻击者编写的,因为 Agent 可能会被所读取的内容注入提示词。防护分为相互独立的多个层面,每个层面都单独测试:
- 查询采用允许列表策略。 使用 sqlglot 解析 SQL,且查询必须恰好是一个 SELECT,只能由经过审核的结构和函数构成。其他任何内容都会被拒绝,无需事先逐一预料:表函数、
LATERAL、SUMMARIZE、递归 CTE,以及所有供应商函数,例如SYSTEM$…、READ_FILES、SECRET、HTTP_REQUEST或GETENV。 - 根据真实架构解析。
*会展开,且每个列都必须解析为已知表中的真实列,包括通过别名、CTE 和子查询解析;将整行用作值也会被拒绝。 - 在 SQL 内屏蔽 PII。 查询发出前,任何选择列表中的 PII 列都会变成
'***',因此其值永远不会离开数据仓库。可以对其计数(COUNT(DISTINCT email)),但不允许基于它筛选、排序、分组或计算,因此无法通过一次次测试猜出其值。 - 锁定连接权限。 DuckDB 以只读模式打开,并禁用外部文件和网络访问,同时锁定其配置。Snowflake 使用仅允许 SELECT 的角色,并移除次要角色;管理员角色会被拒绝。Databricks 使用仅获授
USE和SELECT权限的主体。 - 限制执行和结果。 每条查询都有行数上限、超时限制、单个值的大小上限和总字节数上限。对于包含 PII 的表,会隐藏数据仓库错误消息,因为其中可能包含具体值。
**范围:**仅限配置架构中的表;表名按照对应方言自身的大小写规则进行比较,实际执行的 SQL 中每个表都使用完全限定名。
数据仓库中存储的 PII 标签(Snowflake 标签、Unity Catalog 列标签)会与整理后的目录合并,且启动时必须可读取(否则拒绝启动),并每 10 分钟刷新一次。对于生产数据,还应使用数据仓库原生的屏蔽功能(屏蔽策略或列屏蔽):服务端屏蔽是纵深防御的一环。
独立审查中用于攻破早期版本的查询位于 tests/attacks/,每次提交都会运行。请参阅威胁模型、ADR 0004 和 SECURITY.md。
快速开始
无需克隆即可试用(需要 uv);--demo 会启动随附的完全合成的运输数据仓库,并在首次运行时构建:
uvx warehouse-context-mcp --demo
也可通过 PyPI、容器镜像(ghcr.io/andremuraro/warehouse-context-mcp)以及 MCP Registry 获取,注册名称为 io.github.AndreMuraro/warehouse-context-mcp。每个版本都附带构建来源证明;请参阅 SECURITY.md。
在 MCP 客户端中使用
克隆仓库后即可直接使用:.mcp.json(Claude Code)、.vscode/mcp.json(VS Code)和 .codex/config.toml(Codex)都会启动演示服务。每个客户端都会在信任项目的服务前征求确认。
若要改为在所有客户端中添加:
| 客户端 | 命令或配置 |
|---|---|
| Claude Code | claude mcp add --scope user warehouse -- uvx warehouse-context-mcp --demo |
| Claude Desktop | 在 mcpServers 下的 claude_desktop_config.json 中添加:"warehouse": {"command": "uvx", "args": ["warehouse-context-mcp", "--demo"]} |
| VS Code | 在 servers 下的用户级 mcp.json 中添加:"warehouse": {"type": "stdio", "command": "uvx", "args": ["warehouse-context-mcp", "--demo"]} |
| Codex | codex mcp add warehouse -- uvx warehouse-context-mcp --demo |
| 任意客户端,通过 HTTP | 运行 docker compose up,然后将客户端指向 http://127.0.0.1:8000/mcp |
Claude Code 插件和 Agent 技能
该代码库也是 Claude Code 插件市场。该插件打包了服务和一个 warehouse-context 技能,用于教会 Agent 工作流(查找、描述、检查新鲜度、查询、引用已执行的 SQL),以及如何回应拒绝请求:
/plugin install warehouse-context --marketplace AndreMuraro/warehouse-context-mcp
同一技能也已纳入项目:.claude/skills/(Claude Code)、.agents/skills/(Codex),且 VS Code 会读取这两个目录。或者,将 plugins/warehouse-context/skills/warehouse-context/ 复制到你的个人技能文件夹。
将 --demo 替换为 --backend snowflake 或 --backend databricks(并使用下方的设置),即可连接真实数据仓库。
然后提问:“上个季度,哪个船舶类别的平均 TCE 最佳?该表的数据是否新鲜?”
开发
需要 uv;如果缺少 Python 3.14,uv 会安装它。
uv sync --all-extras # creates .venv from uv.lock
uv run pytest
Snowflake 或 Databricks
uv sync --extra snowflake # or --extra databricks, or --all-extras
cp .env.example .env # fill in your own values; .env is git-ignored
# run examples/snowflake_demo.sql (or databricks_demo.sql) once in the warehouse
uv run warehouse-context-mcp --backend snowflake --catalog path/to/catalog.yaml
设置来自 SNOWFLAKE_* / DATABRICKS_* 环境变量或 ./.env;实际环境变量优先,空值视为未设置。Snowflake 的密钥对身份验证:uv run scripts/snowflake_keypair.py 会输出需要执行的唯一一条 ALTER USER 语句。
共享 Snowflake CLI 连接
如果你使用 Snowflake CLI,可以让服务使用其中一个连接,而无需重复填写账户和登录信息:
# connections.toml (~/.snowflake/, or %USERPROFILE%\AppData\Local\snowflake\ on Windows)
[wcm]
account = "orgname-accountname"
user = "you"
authenticator = "SNOWFLAKE_JWT"
private_key_file = "~/.snowflake/snowflake_key.p8"
snow sql -c wcm -f examples/snowflake_demo.sql # one-time demo setup, as an admin role
SNOWFLAKE_CONNECTION_NAME=wcm SNOWFLAKE_ROLE=WCM_READER uv run warehouse-context-mcp --backend snowflake
连接会提供账户和登录信息;你设置的任何 SNOWFLAKE_* 值都会覆盖连接中的值,而本软件包的默认值不会覆盖它们。连接后,服务会采用会话的实际数据库和架构,并拒绝管理角色(ACCOUNTADMIN、SYSADMIN、……),因此,用于管理工作的 CLI 连接无法绕过仅允许 SELECT 的角色限制。
实时测试会在真实数据仓库中运行演示预期;否则会跳过:
WCM_LIVE=snowflake uv run pytest -m live
在 Windows 上,相同命令可在 PowerShell 中运行;使用 $env:WCM_LIVE = "snowflake" 设置变量。
在 Databricks Free Edition 中,个人访问令牌属于工作区管理员,因此只读连接层在此不可用;查询策略仍然适用。在真实工作区中,请使用仅授予 USE 和 SELECT 权限的服务主体。
Python 版本
| 3.14 | 3.15 | |
|---|---|---|
| 核心、DuckDB | ✓ | ✓ |
| Databricks 附加组件 | ✓ | ✓(lz4 和 thrift 从源代码构建) |
| Snowflake 附加组件 | ✓ | 尚不可用:没有 3.15 轮子,且源代码构建失败;该附加组件会通过环境标记跳过 |
HTTP 传输和容器
默认情况下,服务通过 stdio 使用 MCP:由客户端启动。使用 --transport http 时,服务会改为作为长期运行的 Streamable HTTP 服务运行,返回无状态 JSON 响应,并提供 /healthz 端点:
uv run warehouse-context-mcp --demo --transport http --port 8000
claude mcp add --transport http warehouse http://127.0.0.1:8000/mcp
HTTP 传输没有身份验证。即使绑定到所有接口,DNS 重绑定防护仍会保持启用:只会处理 Host 标头中名称为 localhost 或通过 --allowed-host 传入的请求。请将其发布到 loopback,或在前面部署身份验证代理。
Docker
docker compose up --build # demo warehouse at http://127.0.0.1:8000/mcp
docker run --rm -i warehouse-context-mcp:local # or stdio, for clients that launch a command
该镜像基于 uv.lock 构建,以非 root 用户身份运行,并包含所有后端以及合成演示数据仓库。Compose 使用只读文件系统、禁用所有 Linux 功能并启用 no-new-privileges 运行该镜像,且仅在 127.0.0.1 上发布端口。
要连接真实数据仓库,请填写 .env 并启动一个配置档。凭据会以机密文件的形式传入容器,存放在 /run/secrets 下,而非作为环境变量传入:
docker compose --profile snowflake up --build # :8001, key-pair sign-in (no browser in a container)
docker compose --profile databricks up --build # :8002, token from DATABRICKS_TOKEN
- Snowflake 使用
SNOWFLAKE_ACCOUNT、SNOWFLAKE_USER和SNOWFLAKE_PRIVATE_KEY_PATH指定的密钥文件;Snowflake CLI 连接名称仅为主机端提供便利。 - **Linux 主机:**如果只有你自己能读取密钥文件,请以自己的用户身份运行:
WCM_UID=$(id -u) WCM_GID=$(id -g) docker compose ...。 - 版本标签会将镜像发布到
ghcr.io/andremuraro/warehouse-context-mcp。
CI 会构建镜像、检查 stdio 传输、启动 Compose 服务直至其健康就绪、通过 HTTP 调用一个工具、确认拒绝外部 Host 标头,并验证容器以非 root 用户身份运行且文件系统为只读。
目录
语义存放在 YAML 文件中,并像代码一样在 Git 中审核(演示项目的目录):
tables:
fct_voyage_economics:
description: Time-charter-equivalent economics per voyage.
owner: freight-analytics
grain: voyage_id
upstream: [stg_voyages]
freshness_column: computed_at
expected_freshness_hours: 12
columns:
tce_usd_per_day: { description: TCE in USD per day. }
在生产环境中,它可以由 dbt 文档、Unity Catalog 注释或数据目录生成。
架构
src/warehouse_context_mcp/
├── demo/ the bundled synthetic warehouse and its catalog
├── domain/ catalog, result models, namespace, errors (no I/O beyond YAML)
├── guardrails/ QueryPolicy: parse, scope, PII rules, row limit; result masking
├── warehouses/ Warehouse protocol + DuckDB, Snowflake, Databricks adapters
├── service.py WarehouseContext: combines the three; no MCP dependency
├── server.py MCP transport: six read-only tools, stdio or Streamable HTTP
├── settings.py pydantic-settings for connection config and secrets
└── cli.py entry point
依赖关系由外向内:传输层了解服务层,服务层了解领域层、护栏和 Warehouse 协议,而领域层中的任何内容都不依赖 MCP 或任何驱动程序。
- **端到端类型化。**工具结果是冻结的 pydantic 模型,因此 MCP 客户端能为每种输出接收 JSON schema。工具参数的限制(
depth为 1–5,max_rows≤ 1000)会写入输入 schema。DB-API 驱动程序通过Cursor[P]协议访问,该协议针对驱动程序的 paramstyle 进行泛型化,因此将位置参数绑定到命名参数风格的驱动程序会导致类型错误。 - **将错误作为数据处理。**护栏拒绝会以
{"ok": false, "error": ...}的形式返回,供 Agent 修正查询;编程错误和未知表则会引发异常。 - **与数据仓库无关的核心。**适配器只描述元数据的位置;数据获取、缓存、允许列表和目录组装均由
DbApiWarehouse统一处理。
请参阅 docs/adr,了解护栏和工具链背后的决策。
开发
uv run ruff format # format
uv run ruff check # lint: every ruff rule, with a short documented ignore list
uv run ty check # type check, strict rules
uv run pytest --cov # tests with branch coverage
CI 会在 Python 3.14 和 3.15(Linux)以及 Python 3.14(Windows)上运行相同的检查,并构建和冒烟测试 wheel。
路线图
- v0.1:DuckDB 适配器、目录、六个工具、三层护栏、测试、CI
- v0.2:Snowflake 和 Databricks Unity Catalog 适配器、原生注释和 PII 标签、schema 范围限定
- v0.3:Python 3.14+、uv、ruff 和 ty;分层软件包;类型化工具输入和输出;表名由策略限定
- v0.4:Streamable HTTP 传输、强化的容器镜像和 Compose 配置、Snowflake CLI 连接、零配置
--demo、客户端配置、PyPI 和 MCP Registry 发布流水线 - 从 dbt
manifest.json导入目录 - 评估:回答 20 个分析师问题,分别比较启用和未启用服务端的情况,并按答案正确性和表选择评分
- 按工具记录审计日志
许可证
MIT
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。