BigQuery MCP服务器
这是什么? 🤔
这是一个让你的LLM(如Claude)直接与你的BigQuery数据通信的服务器!把它想象成一个友好的翻译器,坐在你的人工智能助手和数据库之间,确保他们可以安全有效地聊天。
快速示例
You: "What were our top 10 customers last month?"
Claude: *queries your BigQuery database and gives you the answer in plain English*不再需要手工编写SQL查询,只需与您的数据自然聊天即可!
它是如何工作的? 🛠️
该服务器使用模型上下文协议(MCP),它就像人工智能数据库通信的通用翻译器。虽然MCP旨在与任何AI模型配合使用,但现在它可以在Claude Desktop中作为开发人员预览版使用。
以下是您需要做的一切:
- 设置身份验证(见下文)
- 将您的项目详细信息添加到Claude Desktop的配置文件中
- 开始自然地与您的BigQuery数据聊天!
它能做什么? 📊
- 只需用简单的英语提问即可运行SQL查询
- 访问数据集中的表和物化视图
- 探索数据集模式,明确标注资源类型(表与视图)
- 在可配置的安全范围内分析数据(通过config.json配置)
- 保护敏感数据 --定义字段级访问限制,以防止AI代理读取PII、PHI、财务数据和机密。代理收到关于如何使用聚合或
EXCEPT子句,因此它在不暴露单个记录的情况下仍然有用。 - 自动发现敏感字段 -自动扫描整个BigQuery数据仓库中与敏感模式匹配的列(姓名、电子邮件、SSN、医疗记录、API密钥等),并将其添加到限制列表中。每次扫描时,新的表和列都会自动受到保护,无需手动维护。
- 完全可配置 --一切都是由
config.json添加您自己的检测模式以匹配您组织的命名约定(例如。,%guardian_name%,%beneficiary%),调整扫描频率,设置计费限制,并定义每个表的字段限制。扫描仪在下次运行时拾取您的自定义模式,并自动保护所有数据集中的任何匹配列。
哪种设置适合您?
| 简单模式 | 保护模式 | |
|---|---|---|
| 使用时间 | 个人项目、非敏感数据 | PHI、PII、财务数据、HIPAA监管环境 |
| 安装 | npx --无需本地设置 | npx 或本地构建 config.json |
| 现场限制 | 无 | 定义 preventedFields 阻止敏感列 |
| 自动扫描仪 | 不可用 | 自动发现所有数据集中的敏感列 |
| 设置 | 快速设置 在......下面 保护模式设置 在......下面 |
为什么本地部署对敏感数据很重要: LLM推理发生在云中。当AI代理查询BigQuery时,结果会被发送到LLM提供商的服务器(Anthropic、OpenAI等)进行处理——它们会离开您的网络。BigQuery IAM控制谁可以 *到达* 您的数据;现场限制控制什么 *AI代理表面生成LLM响应*这些是不同的保护边界。配置 preventedFields 确保PHI和PII永远不会进入LLM对话上下文,无论代理自主运行多少查询。
快速开始🚀
先决条件
- Node.js 14或更高版本
- 启用BigQuery的Google Cloud项目
- 已安装Google Cloud CLI或服务帐户密钥文件
- Claude Desktop(目前唯一支持的LLM界面)
快速设置
- 使用Google Cloud进行身份验证:
gcloud auth application-default login- 添加到您的Claude桌面配置 (
claude_desktop_config.json):
{
"mcpServers": {
"bigquery": {
"command": "npx",
"args": [
"-y",
"@ergut/mcp-bigquery-server",
"--project-id",
"your-project-id"
]
}
}
}- 开始聊天! 打开克劳德桌面,询问有关数据的问题。
保护模式设置
对于具有字段级限制的敏感数据:
- 使用Google Cloud进行身份验证 (选择一种方法):
- 使用Google Cloud CLI(非常适合开发):
gcloud auth application-default login- 使用服务帐户(建议用于生产):
# Save your service account key file and use --key-file parameter
# Remember to keep your service account key file secure and never commit it to version control- 添加到您的Claude桌面配置 (
claude_desktop_config.json):
- 使用应用程序默认凭据:
{
"mcpServers": {
"bigquery": {
"command": "npx",
"args": [
"-y",
"@ergut/mcp-bigquery-server",
"--project-id",
"your-project-id",
"--location",
"us-central1",
"--config-file",
"/path/to/config.json"
]
}
}
}- 使用服务帐户密钥文件:
{
"mcpServers": {
"bigquery": {
"command": "npx",
"args": [
"-y",
"@ergut/mcp-bigquery-server",
"--project-id",
"your-project-id",
"--location",
"us-central1",
"--key-file",
"/path/to/service-account-key.json",
"--config-file",
"/path/to/config.json"
]
}
}
}- 开始聊天!
打开克劳德桌面,开始询问有关数据的问题。
配置
服务器支持可选 config.json 高级配置文件。没有配置文件(即没有 --config-file 标志),服务器以简单模式运行,具有安全默认值(1GB查询限制,无字段限制)。要启用保护,请通过 --config-file /path/to/config.json 启动服务器时。
config.json结构
{
"maximumBytesBilled": "1000000000",
"preventedFields": {
"healthcare.patients": ["first_name", "last_name", "ssn", "date_of_birth", "email"],
"billing.transactions": ["credit_card_number", "bank_account"]
},
"sensitiveFieldPatterns": [
"%first_name%", "%last_name%", "%email%",
"%ssn%", "%date_of_birth%", "%password%"
],
"sensitiveFieldScanFrequencyDays": 1
}| 设置 | 默认值 | 说明 |
|---|---|---|
maximumBytesBilled | "1000000000" (1GB) | 每次查询计费的最大字节数 |
preventedFields | {} | 受限字段的表到列映射 |
sensitiveFieldPatterns | 内置集 | 用于自动发现的SQL LIKE模式 |
sensitiveFieldScanFrequencyDays | 1 | 自动扫描之间的天数(0 禁用) |
命令行参数
--project-id:(必填)您的Google Cloud项目ID--location:(可选)BigQuery位置,默认为“US”--key-file:(可选)服务帐户密钥JSON文件的路径--config-file:(可选)配置文件的路径,默认为“config.json”--maximum-bytes-billed:(可选)覆盖查询计费的最大字节数,覆盖config.json值
使用服务帐户的示例:
npx @ergut/mcp-bigquery-server --project-id your-project-id --location europe-west1 --key-file /path/to/key.json --config-file /path/to/config.json --maximum-bytes-billed 2000000000保护敏感数据🔒
数据仓库通常包含高度敏感的信息——患者记录、社会保险号码、财务数据、个人联系方式和身份验证机密。当AI代理可以直接访问您的BigQuery仓库时, 没有人在循环中阻止它读取敏感列.一个简单的查询,如 SELECT * FROM patients 可能会在一次响应中暴露数千条PII/PHI记录。
该服务器为管理员提供了对AI代理可以访问哪些列的精细控制,确保敏感数据得到保护,同时仍允许AI对非敏感字段执行有用的分析查询。
安全模型:协作护栏,而不是SQL防火墙
重要提示: 此服务器中的字段限制和表分配列表设计为 人工智能代理的合作护栏,而不是作为对抗敌对攻击者的硬安全边界。
威胁模型很简单:当AI代理查询您的BigQuery仓库时,查询结果会被发送到LLM提供商的服务器。字段限制可防止代理在这些结果中无意中包含敏感列(PII、PHI、机密)。当代理遇到限制错误时,它会读取错误消息中的指导,并使用聚合函数重新制定其查询, EXCEPT 子句,或者只是删除受限字段。在实践中,人工智能代理会立即并一致地进行合作。
该系统使用基于正则表达式的SQL分析来检测受限字段的使用情况。我们在开发过程中进行了渗透测试,并修复了几个旁路向量(结构别名扩展、逗号连接规避、隐式 SELECT *).然而,基于正则表达式的解析无法保证覆盖所有可能的SQL构造——可能存在涉及深度嵌套CTE、奇异BigQuery语法或对抗性查询制作的边缘情况。执行逻辑旨在 故障关闭 (阻止不明确的查询,而不是允许它们),但这并不等同于数据库级的安全策略。
这是什么:
- 有效的指导,防止人工智能代理在正常使用中访问敏感数据
- 捕获常见查询模式的安全网(
SELECT *、直接字段引用、别名) - 针对通过渗透测试发现的已知旁路技术进行加固
这不是什么:
- BigQuery IAM、列级安全或行级访问策略的替代品
- 针对恶意人类故意制造旁路查询的防御
- 经过认证的SQL解析器——它使用模式匹配,而不是完整的AST
对于需要严格合规保证的环境,请将这些防护措施与BigQuery的本机结合使用 列级安全 和 授权视图.
保护模式
服务器支持三种保护模式,通过配置 protectionMode 在 config.json:
| 模式 | 描述 | 默认值 |
|---|---|---|
off | 无保护--所有表和字段均可访问 | 不存在配置文件 |
allowedTables | 表满列表--只能查询列出的表 | 必须显式设置 |
autoProtect | 自动扫描敏感字段,强制执行 preventedFields | 配置文件存在,但没有 protectionMode 钥匙 |
allowedTables 模式
将AI代理限制在一组特定的表中。对任何其他表的查询都会立即被拒绝。在允许的表中定义字段限制(可选):
{
"protectionMode": "allowedTables",
"maximumBytesBilled": "10000000000",
"allowedTables": [
"analytics.page_views",
"analytics.sessions",
"reporting.daily_summary"
],
"preventedFieldsInAllowedTables": {
"analytics.page_views": ["user_ip", "user_agent"]
}
}preventedFieldsInAllowedTables是可选的--默认为{}(允许的表内没有字段限制)- 自动扫描可以 不 在此模式下运行--所有限制都是手动配置的
INFORMATION_SCHEMA查询始终允许用于模式发现
autoProtect 模式(字段级别限制)
原始保护模式。自动扫描BigQuery数据集的敏感列并强制执行 preventedFields.手动输入 preventedFields 在扫描过程中保持不变(合并仅是累加的)。详见下文。
没有的现有配置文件 protectionMode 继续工作——它们默认为 autoProtect 为了向后兼容性。
现场级访问限制
定义 preventedFields 在配置中阻止AI代理访问特定列:
{
"preventedFields": {
"healthcare.patients": ["first_name", "last_name", "ssn", "date_of_birth", "email"],
"billing.transactions": ["credit_card_number", "bank_account"]
}
}当AI代理尝试访问受限字段时会发生什么:
SELECT first_name, last_name, diagnosis FROM healthcare.patients服务器阻止查询并返回一个明确的、有指导意义的错误:
Restricted fields detected for table "healthcare.patients" columns "first_name", "last_name".
You can only use these columns inside ["count", "countif", "avg", "sum"]
aggregate functions or exclude them with SELECT * EXCEPT (...).AI代理从这个错误中学习并自动调整其查询。它仍然可以运行不暴露单个敏感值的分析查询:
-- Allowed: aggregate functions don't expose individual values
SELECT COUNT(first_name) AS patient_count, diagnosis
FROM healthcare.patients
GROUP BY diagnosis
-- Allowed: explicitly excluding restricted fields
SELECT * EXCEPT(first_name, last_name, ssn, date_of_birth, email)
FROM healthcare.patients查询模式参考:
| 查询模式 | 行为 |
|---|---|
SELECT restricted_col FROM table | 已阻止,并显示错误消息 |
SELECT * FROM table | 已阻止(将暴露受限字段) |
SELECT * EXCEPT(restricted_cols) FROM table | 允许 |
COUNT(restricted_col), AVG(...), SUM(...), COUNTIF(...) | 允许(聚合不暴露单个值) |
MIN(restricted_col), MAX(restricted_col) | 已阻止(返回实际的单个值) |
SELECT non_restricted_col FROM table | 允许 |
SELECT id FROM table WHERE restricted_col = '...' | 已阻止(见下文注释) |
SELECT id FROM table ORDER BY restricted_col | 已阻止(见下文注释) |
注意:WHERE、ORDER BY和其他子句中的受限字段被阻止,而不仅仅是SELECT中的字段。即使查询结果不包含受限列,完整的SQL查询文本也会作为对话的一部分发送给LLM提供程序。一个类似的查询 WHERE email = 'patient@example.com' 表示受限值出现在发送到云端的提示中。执法部门会检查整个查询,以防止受限数据以任何形式离开您的网络。服务器端日志记录: 每个被阻止的查询都会记录在服务器端,让管理员可以看到AI代理试图访问的内容:
Query tool error: Error: Restricted fields detected for table "healthcare.patients" columns "first_name", "last_name".自动灵敏场扫描仪
手动列出数百个表中的每个敏感列是不切实际的。该服务器包括一个自动扫描程序,可以发现整个数据库中的敏感列 全部 通过查询您的BigQuery数据集 INFORMATION_SCHEMA.COLUMNS 具有可配置的SQLLIKE模式。发现的字段会自动添加到 preventedFields 在您的配置中。
运作原理
- 扫描程序对BigQuery项目中的所有列名运行SQLLIKE模式匹配
- 与以下模式匹配的列
%first_name%,%ssn%,%email%被确定为敏感 - 发现的列将合并到您的配置中
preventedFields - 合并是 仅限添加剂 --手动添加的限制永远不会被删除
服务器启动时自动扫描
当MCP服务器启动时,它会根据以下内容检查配置文件是否过时 sensitiveFieldScanFrequencyDays。如果过时,它会自动扫描并更新配置:
Config is stale (scan frequency: 1 day(s)), running sensitive field scan...
Scanning all datasets for sensitive fields...
Found 1166 sensitive column(s) across 278 table(s)
Scan complete: config updated with 278 tables.这意味着 具有敏感列的新表将自动受到保护 无需任何手动配置。随着数据仓库的增长,扫描仪也会跟上。
通过CLI手动扫描
随时按需运行扫描:
npm run scan-fields -- --project-id your-project-id --config-file ./config.json为您的组织定制模式
默认模式包括常见的命名约定(姓名、电子邮件、SSN、出生日期、医疗记录号、保险ID、密码、API密钥等),但每个组织都有自己的。添加自定义模式以匹配您的模式:
{
"sensitiveFieldPatterns": [
"%first_name%", "%last_name%", "%email%", "%ssn%",
"%date_of_birth%", "%password%", "%api_key%",
"%guardian_name%",
"%emergency_contact%",
"%beneficiary%",
"%next_of_kin%"
]
}在下次自动扫描(或手动扫描)时 npm run scan-fields),扫描仪会拾取与新图案匹配的列,并自动将其添加到 preventedFields。随着数据仓库的增长和新表的添加,任何与您的模式匹配的列都是 自动保护 无需人工干预。
扫描仪配置
| 设置 | 默认值 | 说明 |
|---|---|---|
sensitiveFieldPatterns | 内置集,涵盖姓名、联系人、身份、保险和机密 | SQL LIKE模式,与列名相匹配 |
sensitiveFieldScanFrequencyDays | 1 (每日) | 自动扫描之间的天数。集 0 禁用自动扫描。 |
需要权限
你需要其中之一:
roles/bigquery.user(推荐)- 或两者皆有:
- roles/bigquery.dataViewer - roles/bigquery.jobUser
本地构建(可选)🔧
运行本地构建,而不是 npx --可用于贡献、测试更改或运行固定版本。支持简单模式和保护模式。
# Clone and install
git clone https://github.com/ergut/mcp-bigquery-server
cd mcp-bigquery-server
npm install
# Build
npm run build然后更新您的Claude Desktop配置以指向您的本地版本:
- 简单模式 (无配置文件):
{
"mcpServers": {
"bigquery": {
"command": "node",
"args": [
"/path/to/your/clone/mcp-bigquery-server/dist/index.js",
"--project-id",
"your-project-id",
"--location",
"us-central1"
]
}
}
}- 保护模式 (带配置文件):
{
"mcpServers": {
"bigquery": {
"command": "node",
"args": [
"/path/to/your/clone/mcp-bigquery-server/dist/index.js",
"--project-id",
"your-project-id",
"--location",
"us-central1",
"--key-file",
"/path/to/service-account-key.json",
"--config-file",
"/path/to/config.json"
]
}
}
}
## Current Limitations ⚠️
- The configuration examples above are shown for Claude Desktop and Claude Code, but any MCP-compatible client can use this server — provide the same JSON configuration to your AI agent and it will adapt to its own setup
- Queries are read-only with configurable processing limits (set in config.json)
- While both tables and views are supported, some complex view types might have limitations
- A config.json file is optional; without one the server uses safe defaults
## Support & Resources 💬
- 🐛 [Report issues](https://github.com/ergut/mcp-bigquery-server/issues)
- 💡 [Feature requests](https://github.com/ergut/mcp-bigquery-server/issues)
- 📖 [Documentation](https://github.com/ergut/mcp-bigquery-server)
## License 📝
MIT License - See [LICENSE](LICENSE) file for details.
## Author ✍️
Salih Ergüt
## Sponsorship
This project is proudly sponsored by:
## Version History 📋
See [CHANGELOG.md](CHANGELOG.md) for updates and version history.```