关于 Pinot MCP Server
Pinot MCP Server 是一个基于 Python 和 FastMCP 的 Apache Pinot MCP 服务,面向通过 Claude Desktop 查询集群数据和元数据的用户。它支持只读 SQL、分页结果与带预览和确认令牌的变更操作。
主要功能
- 01查看表、分段及 schema 信息
- 02执行只读 SQL 查询
- 03检查列级索引和表配置
- 04对大型响应进行分页
- 05变更操作支持 dry_run 和确认令牌
- 06返回查询完整性及执行计时信息
适用场景
- 01检查 Pinot 集群连接和表结构
- 02查询 Pinot 数据并查看执行完整性
- 03检查指定分段的列索引元数据
- 04预览并确认 schema 或表配置变更
MCP 相关
它通过 MCP 向客户端提供 Pinot 集群连接诊断、元数据查询、只读 SQL,以及受预览和确认令牌保护的变更工具。支持 stdio 和 HTTP 传输。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx mcp-pinot-serverPINOT_CONTROLLER_URLHTTP(S) endpoint of the Pinot Controller.PINOT_BROKER_URLHTTP(S) endpoint of the Pinot Broker.PINOT_USERNAMEOptional Pinot basic-auth username.PINOT_PASSWORD密钥Optional Pinot basic-auth password.PINOT_TOKEN密钥Optional Pinot bearer token. Overrides username and password when set.PINOT_USE_MSQEWhether to enable Pinot multi-stage query engine support.MCP_TRANSPORTTransport mode: 'stdio' (default, for desktop clients) or 'http'.AUTH_PROVIDER密钥Inbound auth provider for HTTP transport (e.g. 'oauth'); required to bind a non-loopback host.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
18收录的工具列表 · 更新于 3 周前
此工具无需参数。
详细介绍
Pinot MCP 服务
目录
概述
本项目是一个基于 Python 的 Model Context Protocol (MCP) 服务,用于与 Apache Pinot 交互。它使用 FastMCP framework 构建,旨在与 Claude Desktop 集成,以便对 Pinot 集群进行实时分析和元数据查询。
它可以帮助你:
- 列出 Pinot 中的表、分段和架构信息
- 执行只读 SQL 查询
- 查看索引和列级元数据
- 旨在通过 Claude 集成帮助业务用户
- 以及更多功能。
功能
- 每个工具都会公布类型化的输入和输出 JSON Schema、MCP 风险注释,以及用于 Agent 规划的故障恢复指南。
- 大型查询、表、分段名称和分段元数据响应采用有界分页,并提供续传元数据,而不是返回不受限制的 Agent 上下文。
- 执行前会解析并强制执行只读 SQL;验证、权限和暂时性连接错误会以可操作的 MCP 错误形式呈现。
- 每个修改型工具都支持
dry_run;应用前务必预览确切的目标和负载。应用操作需要使用预览返回的短时有效、一次性confirmation_token,重新加载表筛选条件也不例外。预览并不保证 Pinot 会接受后续写入。 - 专用的架构和表配置检查工具可避免含义不明确的组合操作:请分别使用
get_schema和get_table_config。
MCP 工具契约
工具名称区分大小写,并使用下划线。版本 4 重命名了四个工具,使每项操作都以动词开头;使用旧版名词开头名称的客户端必须更新调用。
| 工具 | 用途 |
|---|---|
test_connection | 诊断 broker、controller 和查询的连通性。 |
list_tables | 列出可见的 Pinot 表名称。 |
get_schema | 获取一个表的列架构。 |
get_table_config | 获取一个表的索引和摄取配置。 |
get_table_size | 获取一个表已报告和估算的存储大小。 |
list_segments | 列出一个表的确切 segment 名称。 |
list_segment_metadata | 分页获取一个表各 segment 的元数据。 |
get_segment_index_metadata | 检查一个确切 segment 的各列索引。 |
read_query | 运行一条只读 Pinot SQL 查询。 |
begin_investigation / query_incident | 开启并查询一项选择加入的限定范围证据运行。 |
get_trace / finish_investigation | 获取已记录的跨度边,并附带引用关闭调查。 |
create_schema / update_schema | 预览或应用架构变更。 |
create_table_config / update_table_config | 预览或应用表配置变更。 |
reload_table_filters | 预览或应用已配置的表过滤器 YAML。 |
对于任何架构、表配置或表过滤器变更,都必须先使用 dry_run=true 调用相同工具,将预览结果展示给用户,并且只有在获得确认后,才使用 dry_run=false 和预览中的一次性 confirmation_token 调用该工具。在预览后编辑表过滤器文件会使其令牌失效。Pinot 会在应用表或架构的调用期间执行权威验证,因此即使预览成功,写入仍可能失败。
查询执行证据
read_query 除现有分页字段外,还会返回 metadata。例如,{"query":"SELECT service, count(*) FROM events GROUP BY service","limit":20} 返回的 metadata.completeness 为 complete、partial 或 unknown,并附带原生服务端计数、查询 ID、查询 SHA-256 和有界执行统计信息。缺少 resultTable 或必需的执行标志时,结果仍为 unknown。服务端响应不完整或达到分组上限时,结果为 partial;空页面并不能证明遥测正常。原生的 complete 表示这次有界 SQL 执行完整,并不代表覆盖了整个事件时间窗口或整个数据集。row_limit_reached 与执行完整性和分页是分开的。
MCP 查询路径通过 cursor.execute_native() 使用 pinotdb>=9.2.1 提交并解码查询。SDK 会公开完整的结构化 query_statistics;MCP 则将有界计数器和安全的执行证据映射到工具响应中。该路径只会提交一次,遇到结果不明确的故障时不会切换传输方式。唯一的 clientQueryId 和 applicationName=mcp-pinot 支持在条件允许时与查询历史记录或 broker 日志进行可选关联。Python 集成可以调用 execute_query_with_metadata(..., timeout_seconds=5),以限制原生和 HTTP 超时,而无需修改共享配置。HTTP 超时是非活动时间限制;迟到的结果会被拒绝,但这并非原生取消。
工具结果(包括工具错误)均会在标准 MCP 响应 _meta["io.github.startreedata/mcp-pinot"] 中包含计时证据。现有工具数据和输出架构保持不变。例如,以下响应元数据片段无需访问日志:
{
"_meta": {
"io.github.startreedata/mcp-pinot": {
"request_id": "38cb1444b20c446a96bc272531f34518",
"status": "success",
"admitted": true,
"queue_wait_ms": 12,
"execution_ms": 84,
"duration_ms": 97
}
}
}
MCP 速率限制协议错误会保留其 JSON-RPC 代码和消息,并在 error.data._meta["io.github.startreedata/mcp-pinot"] 中携带相同的封装。其他传输或协议故障以及取消操作可能不会产生工具结果。
在默认端口 8080 上使用 MCP_TRANSPORT=http 时,FastMCP Python 客户端会通过 result.meta 读取线缆 _meta。call_tool_mcp 也会返回工具错误:
from fastmcp import Client
async def read_timing():
async with Client("http://localhost:8080/mcp") as client:
result = await client.call_tool_mcp("read_query", {"query": "SELECT 1"})
return result.meta["io.github.startreedata/mcp-pinot"]
当宿主不会自动呈现协议元数据时,编排器应读取 .meta,并将这些证据转发给 Agent。
queue_wait_ms 仅衡量等待 MCP 并发信号量的时间。execution_ms 衡量获准执行的 MCP 工具流程,包括 SDK HTTP 工作和验证;admitted=false 表示该流程从未启动。duration_ms 覆盖服务端的工具调用,包括准入检查,但不包括模型推理和客户端交付。对于 MCP 结果,status 为 success 或 error;对于 read_query,应单独检查 metadata.completeness。
Agent 可使用 queue_wait_ms 识别 MCP 准入延迟,然后在存在时检查 read_query 的 metadata.native_stats.timeUsedMs,以获取 Pinot 的原生查询耗时。原生查询耗时与 execution_ms 存在重叠;由于两者的计时边界不同,无法据此精确扣除网络开销。共享的 request_id 也会出现在查询元数据和原生 clientQueryId 中,因此在需要更多上下文时,可选择将其与历史记录或日志关联。
响应计时元数据不包含机密、主体标识符、工具参数、SQL 或行数据。审计日志会记录相同的计时信息,并使用经过哈希处理的主体标识符。MCP_MAX_RESPONSE_BYTES 会在添加有大小上限的计时封套之前限制工具负载;不包含新增的可观测性元数据。
未返回响应时,取消操作仅记录在审计日志中,不能证明 Pinot 执行已停止。
在服务端使用 --incident-profiles 启动之前,事件工具处于禁用状态。配置以及使用 begin_investigation、query_incident、可选的 get_trace 和 finish_investigation 的工作流,请参阅事件证据指南和示例配置文件。证据查询会公开相同的响应 _meta 计时信息,以及报告的原生请求 ID;日志访问为可选项。运行与所有者绑定并受预算限制;即使完整执行,根因假设和数据集覆盖范围仍未经验证。此首个版本使用单进程内存状态,并设有大小上限。
Pinot MCP 实战
请查看下方的 Pinot MCP 实战:
获取元数据

获取数据并进行分析
提示词:
你能针对 GitHub 事件随时间变化绘制直方图吗?

示例提示词
Claude 运行后,点击锤子 🛠️ 图标并试试以下提示词:
- 你能帮我分析 Pinot 中的数据吗?请先使用 Pinot 工具查看表格列表。
- 你能针对 GitHub 事件随时间变化绘制直方图吗?
快速开始
前置条件
安装 uv(如果尚未安装)
uv 是一个以 Rust 编写的快速 Python 包安装器和解析器。它旨在作为 pip 的直接替代品,并提供显著更好的性能。
curl -LsSf https://astral.sh/uv/install.sh | sh
# Reload your bashrc/zshrc to take effect. Alternatively, restart your terminal
# source ~/.bashrc
安装
# Clone the repository
git clone https://github.com/startreedata/mcp-pinot.git
cd mcp-pinot
uv pip install -e . # Install dependencies
# For development dependencies (including testing tools), use:
# uv pip install -e .[dev]
配置 Pinot 集群
MCP 服务需要根目录下采用 uvicorn 配置风格的 .env 文件来配置 Pinot 集群连接。本仓库包含一个示例 .env.example 文件,假定使用 pinot quickstart 设置。
mv .env.example .env
配置参考
服务会从环境变量以及当前工作目录中的 .env 文件加载配置。
进程环境变量的优先级高于 .env,因此部署时的设置不会被检出的文件悄然覆盖。
常见配置
| 用例 | 必需设置 | 说明 |
|---|---|---|
| Claude Desktop | MCP_TRANSPORT=stdio | 本地桌面使用时的默认推荐设置;不会启动 HTTP 监听器。 |
| 本地 HTTP | MCP_TRANSPORT=http、MCP_HOST=127.0.0.1 | 显式指定本地 Web 配置。仅可从同一台计算机访问。 |
| 远程 HTTP/HTTPS | MCP_TRANSPORT=http、MCP_HOST=0.0.0.0、MCP_ALLOWED_HOSTS=<host[:port]>、AUTH_PROVIDER=oauth|static|oauth+static | 除非启用了身份验证提供程序,否则服务会拒绝绑定到非环回 HTTP/HTTPS 地址;通配符绑定必须显式设置 Host 允许列表。使用 oauth+static 可同时为交互式用户和一个受信任的后端提供服务。直接使用 TLS,或使用经过身份验证的反向代理。 |
| Helm 暴露 | service.enabled=true、mcp.host=0.0.0.0、mcp.oauth.enabled=true | Helm 默认仅供本地使用,除非明确启用暴露,否则不会生成 Service。 |
Pinot 连接
| 变量 | 默认值 | 说明 |
|---|---|---|
PINOT_CONTROLLER_URL | http://localhost:9000 | 用于元数据及表/架构操作的 Pinot 控制器端点。 |
PINOT_BROKER_URL | http://localhost:8000 | 用于 SQL 查询的 Pinot Broker 端点。 |
PINOT_BROKER_HOST | 从 PINOT_BROKER_URL 解析 | Broker 连接的可选主机覆盖值。 |
PINOT_BROKER_PORT | 从 PINOT_BROKER_URL 解析 | Broker 连接的可选端口覆盖值。 |
PINOT_BROKER_SCHEME | 从 PINOT_BROKER_URL 解析 | 可选的协议覆盖值,通常为 http 或 https。 |
PINOT_USERNAME / PINOT_PASSWORD | 未设置 | Pinot 的基本身份验证。 |
PINOT_TOKEN | 未设置 | Pinot 的 Bearer 或原始令牌;优先级高于 PINOT_TOKEN_FILENAME。 |
PINOT_TOKEN_FILENAME | 未设置 | 包含 Pinot 令牌的文件:一行可打印的 ASCII 字符,可带或不带 Bearer 前缀。随着请求发出,文件会重新读取,因此会获取轮换后的令牌,例如投射的 Kubernetes 服务账户令牌。如果启动时无法使用该文件(文件缺失、为空、不可读或无效),服务会记录警告,并在重启前不使用令牌身份验证。如果之后发生这种情况,则继续使用上一次读取的令牌;该故障只记录一次,不会在每次请求时重复记录。 |
PINOT_DATABASE | 空 | 多数据库 Pinot 部署的可选数据库请求头。 |
PINOT_USE_MSQE | false | 启用 Pinot 多阶段查询引擎查询选项。 |
PINOT_REQUEST_TIMEOUT | 60 | HTTP 请求超时时间,单位为秒。 |
PINOT_CONNECTION_TIMEOUT | 60 | HTTP 连接超时时间,单位为秒。 |
PINOT_QUERY_TIMEOUT | 60 | SQL 查询超时时间,单位为秒。 |
MCP 服务
| 变量 | 默认值 | 描述 |
|---|---|---|
MCP_TRANSPORT | stdio | 传输模式。桌面客户端使用 stdio,Streamable HTTP 客户端使用 http。 |
MCP_HOST | 127.0.0.1 | HTTP 绑定主机。仅在启用身份验证提供程序时才设置为 0.0.0.0。 |
MCP_PORT | 8080 | HTTP 监听端口。 |
MCP_PATH | /mcp | MCP HTTP 路径。 |
MCP_ALLOWED_HOSTS | 具体绑定地址的精确 host[:port] | MCP 端点接受的 Host 权限列表,以逗号分隔。通配符绑定(0.0.0.0、::)无法推断公开权限,因此默认值为空;在列出客户端使用的名称之前,服务将在启动时退出,例如 mcp.example.com,mcp.example.com:443。 |
MCP_ALLOWED_ORIGINS | 未设置 | 接受的浏览器 Origin 值,以逗号分隔。为空时会拒绝发送 Origin 的请求,但仍允许未发送该字段的客户端。 |
MCP_SSL_KEYFILE | 未设置 | TLS 私钥路径。需要同时设置 MCP_SSL_CERTFILE。 |
MCP_SSL_CERTFILE | 未设置 | TLS 证书路径。需要同时设置 MCP_SSL_KEYFILE。 |
MCP_LOG_LEVEL | INFO | 应用程序日志级别:DEBUG、INFO、WARNING、ERROR 或 CRITICAL。日志写入 stderr,以确保 STDIO 协议输出保持有效。 |
MCP_RATE_LIMIT_RPS / MCP_RATE_LIMIT_BURST | 10 / 20 | 每个主体(已通过身份验证)或对等端(回环 HTTP)的工具调用速率和突发限制。 |
MCP_RATE_LIMIT_MAX_CLIENTS | 10000 | 内存中客户端存储桶的最大数量;最近最少使用的存储桶会被逐出。 |
MCP_RATE_LIMIT_IDLE_TTL_SECONDS | 600 | 速率限制存储桶可被逐出前的空闲时间。 |
MCP_CONFIRMATION_TTL_SECONDS | 300 | 确认令牌的有效期,限制为 30–3600 秒。令牌与进程绑定,重启后会有意失效。 |
身份验证
将 HTTP 或 HTTPS 绑定到非回环主机前,必须配置身份验证提供方。
| 变量 | 默认值 | 描述 |
|---|---|---|
AUTH_PROVIDER | 未设置 | 当前使用的身份验证提供方:none(默认)、oauth、static 或 oauth+static。绑定到非回环主机前必须配置提供方。 |
oauth+static 可在同一部署中同时接受 OIDC 登录和共享令牌——这是常见的托管场景:用户使用浏览器,而受信任的后端无法使用浏览器。两种写法均可;会先检查共享密钥,且每种凭证各自保留其作用域(MCP_STATIC_SCOPES 与 OAUTH_GRANTED_SCOPES)。 | ||
MCP_STATIC_TOKEN | 空 | AUTH_PROVIDER=static 的共享 Bearer 密钥——服务到服务的调用方通过 Authorization: Bearer <token> 发送此密钥。启用静态提供方时必填。 |
MCP_STATIC_SCOPES | pinot:read pinot:write pinot:admin | 授予静态主体的作用域,以空格或逗号分隔。只读服务请使用 pinot:read。 |
OAUTH_ENABLED | false | 旧版标志;设为 true 等同于 AUTH_PROVIDER=oauth。启用 OAuth 身份验证。 |
OAUTH_CLIENT_ID | 空 | OAuth 客户端 ID。 |
OAUTH_CLIENT_SECRET | 空 | OAuth 客户端密钥。 |
OAUTH_BASE_URL | http://localhost:8080 | 此 MCP 服务的公开基础 URL。 |
OAUTH_AUTHORIZATION_ENDPOINT | 空 | 上游授权端点。 |
OAUTH_TOKEN_ENDPOINT | 空 | 上游令牌端点。 |
OAUTH_JWKS_URI | 空 | 用于验证令牌的 JWKS URI。 |
OAUTH_ISSUER | 空 | 预期的令牌颁发者。 |
OAUTH_AUDIENCE | 规范 MCP 资源 URI | 用于验证令牌的受众。默认值为 OAUTH_BASE_URL(不带尾部斜杠)加上 MCP_PATH,这也是 RFC 9728 元数据中公布的值。若提供方颁发的 aud 不同,请显式设置此项——许多提供方(包括 Dex)会将其设为客户端 ID;服务会记录警告并采用你设置的值。 |
OAUTH_GRANTED_SCOPES | pinot:read pinot:write pinot:admin | 授予此提供方所验证的每个主体的 Pinot 作用域,并与令牌已有的作用域合并。由于通用 OIDC 提供方会颁发固定的作用域目录,且无法颁发 pinot:*,因此需要此项;否则,来自有效用户的所有工具调用都会被拒绝。只读部署请设为 pinot:read。 |
OAUTH_EXTRA_AUTH_PARAMS | 未设置 | 可选的 JSON 对象,包含其他授权参数。 |
表筛选
| 变量 | 默认值 | 描述 |
|---|---|---|
PINOT_TABLE_FILTER_FILE | 未设置 | 包含 included_tables glob 模式的 YAML 文件。若已配置但文件不存在,启动将失败。 |
生产环境暴露检查清单和漏洞报告流程,请参阅 SECURITY.md。
配置表筛选(可选)
⚠️ 安全说明: 对于生产环境的访问控制,请使用 Pinot 原生的表级 ACL(自 Pinot 0.8.0 起提供)。此 MCP 服务中的表筛选是一项便于整理表和改善用户体验的功能,并非安全边界。它采用尽力而为的 SQL 解析,不应依赖它来保障安全。
表筛选可控制通过 MCP 服务可见的 Pinot 表。适用于以下情况:
- 降低认知负担:当 Pinot 集群中有数百或数千张表时,聚焦于相关表
- 多租户体验:针对同一 Pinot 集群运行多个 MCP 服务实例,每个实例为不同团队或使用场景显示不同的表子集
- 环境隔离:部署不同的 MCP 服务实例(开发、预发布、生产),每个实例仅显示特定环境中的表
- 隐藏系统表:从最终用户视图中过滤掉内部、测试或已弃用的表
启用表筛选后,所有表操作都会经过筛选,仅显示已配置的表。
过滤内容
表过滤适用于所有 MCP 操作:
- 表列表 - 表列表中仅显示已配置的表
- 查询执行 - 检查 SQL 查询,确保其中引用的所有表(包括 FROM、JOIN、子查询、CTE 等)都符合已配置的模式
- 表操作 - 直接访问表的操作会按表名进行过滤:
- 获取表详情、大小和元数据
- 获取表分段和分段元数据
- 获取索引/列详情
- 获取/更新表配置
- Schema 操作 - Schema 操作会按 Schema 名称进行过滤:
- 获取/创建/更新 Schema
- 创建表配置
设置
复制示例配置文件:
cp table_filters.yaml.example table_filters.yaml
编辑 table_filters.yaml,指定要包含的表:
included_tables:
- production_* # All tables starting with "production_"
- analytics_events # Specific table name
- metrics_* # All tables starting with "metrics_"
在 .env 中配置过滤器文件路径:
PINOT_TABLE_FILTER_FILE=table_filters.yaml
模式匹配
过滤器支持使用标准 Unix 文件名模式匹配的 glob 风格模式:
exact_table_name- 仅匹配此表prefix_*- 匹配所有以「prefix_」开头的表*_suffix- 匹配所有以「_suffix」结尾的表*pattern*- 匹配所有包含「pattern」的表sharded_table_?- 匹配下划线后恰好有一个字符的表(例如,sharded_table_1、sharded_table_a)
查询过滤
启用过滤时,会在执行前检查 SQL 查询:
- 支持的 SQL 功能:FROM 子句、JOIN 子句(INNER、LEFT、RIGHT、OUTER、CROSS)、子查询、CTE(WITH)以及逗号分隔的表列表
- 带引号的标识符:支持双引号(
"table name")和反引号(`table_name`)括起来的表名 - Schema 前缀:支持带 Schema 限定的表名(例如,
database.schema.table) - 注释:检查前会移除 SQL 注释
过滤后的查询示例:
SELECT * FROM allowed_table
JOIN other_table ON allowed_table.id = other_table.id
错误: Query references unauthorized tables: other_table. Allowed tables: allowed_table, prod_*
配置功能
快速失败验证:
- ⚠️ 如果已配置
PINOT_TABLE_FILTER_FILE,但文件不存在,服务将因FileNotFoundError无法启动 - 这样可避免因配置错误而意外显示所有表
- 空过滤器文件或缺少
included_tables键时,将显示所有表(不进行过滤)
全面过滤:
- 所有访问表的 MCP 工具都会在执行前应用过滤
- 所有表访问入口均采用一致的过滤逻辑
- 清晰的错误消息会指出哪些表不符合已配置的模式
禁用表过滤
要禁用表过滤,可以:
- 移除
PINOT_TABLE_FILTER_FILE环境变量,或 - 不要在
.env文件中配置该变量
未配置时,Pinot 集群中的所有表均可见。
如果过滤器文件同时设置了 allow_all: true 和非空的
included_tables,则以显式允许列表为准,服务会记录一条
警告。应用重新加载时,需要使用来自未更改的试运行候选项的令牌。
只读查询强制执行
read_query 工具在将 SQL 转发给 Pinot 之前,始终会先验证 SQL。
它只接受一条语句,且该语句必须是只读的 SELECT 或 WITH ... SELECT 查询。系统会移除 SQL 注释、拒绝以分号串联的多条语句,并拦截写入/DDL/管理关键字。
配置 OAuth 身份验证(可选)
要启用 OAuth 身份验证,请在 .env 文件中设置以下环境变量:
必需变量(当 OAUTH_ENABLED=true 时):
OAUTH_CLIENT_ID:OAuth 客户端 IDOAUTH_CLIENT_SECRET:OAuth 客户端密钥OAUTH_BASE_URL:MCP 服务的基础 URLOAUTH_AUTHORIZATION_ENDPOINT:OAuth 授权端点 URLOAUTH_TOKEN_ENDPOINT:OAuth 令牌端点 URLOAUTH_JWKS_URI:用于验证令牌的 JSON Web Key Set URIOAUTH_ISSUER:令牌颁发者标识符
可选变量:
OAUTH_AUDIENCE:用于验证令牌的受众。默认值为规范的 MCP 资源 URI(OAUTH_BASE_URL+MCP_PATH)。如果提供方签发的aud不同,请设置此变量——例如,某个 IdP 会将客户端 ID 放在此处。OAUTH_GRANTED_SCOPES:授予已验证身份主体的 Pinot 作用域(默认包含全部三个作用域)。使用pinot:read可使部署对所有 OIDC 调用方均为只读。OAUTH_REQUIRED_SCOPES:访问令牌必须已包含的基准作用域(默认不强制要求)。OAUTH_EXTRA_AUTH_PARAMS:以 JSON 对象形式提供的额外授权参数(例如,{"scope": "openid profile"})
工具级授权使用 pinot:read / pinot:write / pinot:admin。通用 OIDC 提供方会签发固定的作用域目录,无法创建此类资源作用域,因此 OAUTH_GRANTED_SCOPES 决定了已验证用户能否调用任何工具——请缩小其范围,而不要让工具不受限制。
配置示例:
OAUTH_ENABLED=true
OAUTH_CLIENT_ID=client-id
OAUTH_CLIENT_SECRET=client-secret
OAUTH_BASE_URL=http://localhost:8000
OAUTH_AUTHORIZATION_ENDPOINT=https://example.com/oauth/authorize
OAUTH_TOKEN_ENDPOINT=https://example.com/oauth/token
OAUTH_JWKS_URI=https://example.com/.well-known/jwks.json
OAUTH_ISSUER=https://example.com
OAUTH_AUDIENCE=http://localhost:8000/mcp
OAUTH_EXTRA_AUTH_PARAMS={"scope": "openid profile"}
运行服务
uv --directory . run mcp_pinot/server.py
你应该会看到表示服务正在运行的日志。
安全说明:
- 默认使用 STDIO。选择 HTTP 时,服务会绑定到
127.0.0.1;只有在启用 OAuth 或静态令牌身份验证,并配合 TLS 或经过身份验证的反向代理时,才应设置MCP_HOST=0.0.0.0。- 如果 HTTP 绑定到非环回主机,且未配置身份验证提供方(
AUTH_PROVIDER=oauth或static,或旧版OAUTH_ENABLED=true),服务将拒绝启动。read_query会在执行前强制要求 SQL 语句为单条只读语句。这是一项防护措施,不能替代 Pinot 身份验证和授权。- 受支持的
mcp[cli]依赖项包含适用于 Streamable HTTP 服务的 DNS 重绑定防护。- 确认重放状态和速率限制桶均为进程本地。请只运行一个服务进程/Helm 副本。图表会拒绝
replicas != 1;水平扩展需要共享状态存储实现。/readyz报告的是 MCP 进程是否就绪,而不是 Pinot 集群的运行状况。请使用test_connection诊断 Pinot 依赖项。
启动 Pinot Quickstart(可选)
使用 docker 启动 Pinot QuickStart:
docker run --name pinot-quickstart -p 2123:2123 -p 9000:9000 -p 8000:8000 -d apachepinot/pinot:1.5.1 QuickStart -type batch
查询 MCP 服务
uv --directory . run examples/example_client.py
此快速入门仅检查所有工具,并查询 airlineStats 表。
Claude Desktop 集成
打开 Claude 的配置文件
vi ~/Library/Application\ Support/Claude/claude_desktop_config.json
添加 MCP 服务条目
{
"mcpServers": {
"pinot_mcp": {
"command": "/path/to/uv",
"args": [
"--directory",
"/path/to/mcp-pinot-repo",
"run",
"mcp_pinot/server.py"
],
"env": {
// You can also include your .env config here
}
}
}
}
将 /path/to/uv 替换为 uv 命令的绝对路径;你可以运行 which uv 来查找该路径。
将 /path/to/mcp-pinot 替换为克隆此仓库的文件夹的绝对路径。
注意:要将服务与 Claude desktop 搭配使用,必须使用 stdio 传输。
你也可以在此处配置环境变量,而不是放在 .env 文件中,以便将多个 pinot 集群作为 MCP 服务连接。
重启 Claude Desktop
Claude 现在会在启动时自动启动 MCP 服务,并识别新的基于 Pinot 的工具。
使用 MCP Bundle
发布工作流会发布 Claude Desktop MCP Bundle(.mcpb)。其 UV
运行时会为用户的平台安装锁定的依赖项,因此一个小型
bundle 即可在 macOS、Linux 和 Windows 上使用。要在本地构建:
npm install -g @anthropic-ai/[email protected]
mcpb validate manifest.json
mcpb pack
打开生成的 .mcpb 文件,即可在 Claude Desktop 中安装。
安全与漏洞报告
有关漏洞报告说明、安全类别以及安全公开 MCP HTTP 端点的检查清单,请参阅 SECURITY.md。
开发者
- MCP 工具定义位于
mcp_pinot/server.py;Pinot HTTP/DB 操作 位于mcp_pinot/pinot_client.py。 - 有关依赖策略、SDK 2 集成变更、验证和回滚,请参阅 MCP SDK 兼容性与迁移。
构建
使用以下命令构建项目:
uv sync --frozen
测试
使用以下命令测试代码库:
uv run pytest --cov=mcp_pinot
构建 Docker 镜像
docker build -t mcp-pinot .
运行容器
docker run --rm -i -v "$(pwd)/.env:/app/config/.env:ro" mcp-pinot
此配置使用默认的 STDIO 传输方式。对于 HTTP/Kubernetes 部署,在绑定到非环回地址之前,请配置入站身份验证提供程序;请参阅上文的配置和 Helm 部分。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。