
Apache Pinot MCP Server
io.github.startreedata由 GitHub 账号 startreedata 发布v5.0.0更新于 Oct 24, 2026
Query and manage Apache Pinot through MCP with typed tools and preview-first safety.
概览
面向 Apache Pinot 的 MCP 服务器:让助手列出表与段、查看 schema 和索引、执行只读 SQL,并以先预览后确认的方式修改 schema 与表配置。
- 可以做什么
- 列出表、段与段元数据,查看列级索引信息
- 读取 schema、表配置与表的存储大小
- 每次调用执行一条只读 SQL 查询,并返回完整性与执行元数据
- 开启限定范围的调查运行并获取记录的 trace span
- 通过 dry-run 与一次性确认令牌预览并应用 schema、表配置和表过滤变更
- 诊断 broker、controller 与查询连通性
- 适用场景
- 适合让助手在 Claude Desktop 等桌面客户端中探查和查询 Pinot 集群做实时分析,或在受控流程下修改 schema 与表配置。
- 运行要求
- 以 stdio 本地运行(Python 包或容器),或以 HTTP 方式运行。需要可访问的 Pinot broker 与 controller 地址(PINOT_BROKER_URL、PINOT_CONTROLLER_URL),以及可选的 Pinot 凭据(PINOT_USERNAME、PINOT_PASSWORD、PINOT_TOKEN)。若将 HTTP 暴露到回环地址之外,需配置 AUTH_PROVIDER 等认证方式(OAuth 或静态令牌)。
安装
在 SourceWeft 中
- 打开 控制台中的 Apache Pinot MCP Server,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
Pinot MCP Server
[Build and Test] [PyPI version] [Python versions] [License: Apache 2.0]
Table of Contents
- Overview
- Features
- Quick Start
- Configuration Reference
- Docker Build
- Claude Desktop Integration
- Try a Prompt
- Security and Vulnerability Reporting
- Developer Notes
- Repo Maintainer
Overview
This project is a Python-based Model Context Protocol (MCP) server for interacting with Apache Pinot. It is built using the FastMCP framework. It is designed to integrate with Claude Desktop to enable real-time analytics and metadata queries on a Pinot cluster.
It allows you to
- List tables, segments, and schema info from Pinot
- Execute read-only SQL queries
- View index/column-level metadata
- Designed to assist business users via Claude integration
- and much more.
Features
- Every tool advertises typed input and output JSON Schemas, MCP risk annotations, and failure-recovery guidance for agent planning.
- Large query, table, segment-name, and segment-metadata responses use bounded pages with continuation metadata instead of returning unbounded agent context.
- Read-only SQL is parsed and enforced before execution; validation, permission, and transient connectivity errors are surfaced as actionable MCP errors.
- Every mutating tool supports
dry_run; always preview the exact target and payload before applying. Applying requires the preview's short-lived, one-timeconfirmation_token, including for table-filter reloads. A preview is not a guarantee that Pinot will accept the later write. - Single-purpose schema and table-config inspection tools avoid ambiguous combined
operations: use
get_schemaandget_table_configindependently.
MCP Tool Contract
Tool names are case-sensitive and use underscores. Version 4 renamed four tools to make every operation verb-first; clients using the former noun-first names must update their calls.
For every schema, table-config, or table-filter change, first call the same tool
with dry_run=true, present the preview to the user, and call it with
dry_run=false and the preview's one-time confirmation_token only after
confirmation. Editing a table-filter file after preview invalidates its token.
Pinot performs authoritative validation during table/schema apply calls, so a
write can still fail after a successful preview.
Query execution evidence
read_query returns the existing page fields plus metadata. For example,
{"query":"SELECT service, count(*) FROM events GROUP BY service","limit":20}
returns metadata.completeness as complete, partial, or unknown, along with
native server counts, query ID, query SHA-256, and bounded execution statistics.
Missing resultTable or required execution flags remains unknown. A partial
server response or group limit remains partial; an empty page is not proof of
healthy telemetry. Native complete describes this bounded SQL execution, not
coverage of the incident window or the entire dataset. row_limit_reached is
separate from execution completeness and paging.
The MCP query path uses pinotdb>=9.2.1 through cursor.execute_native() for
submission and decoding. The SDK exposes full structured query_statistics;
MCP projects bounded counters and safe execution evidence into the tool response.
The path submits once and does not switch transports after an ambiguous failure.
Its unique clientQueryId and applicationName=mcp-pinot support optional
correlation with query history or broker logs when available. Python integrations can
call execute_query_with_metadata(..., timeout_seconds=5) to bound native and
HTTP timeouts without modifying shared configuration. HTTP timeouts are
inactivity limits; late results are rejected, but this is not native cancellation.
Tool results, including tool errors, include timing evidence in the standard
MCP response _meta["io.github.startreedata/mcp-pinot"]. Existing tool data and
output schemas are preserved. For example, this response metadata fragment
requires no log access:
MCP rate-limit protocol errors preserve their JSON-RPC code and message and carry
the same envelope in error.data._meta["io.github.startreedata/mcp-pinot"].
Other transport/protocol failures or cancellation may not produce a tool result.
With MCP_TRANSPORT=http on the default port 8080, a FastMCP Python client reads
wire _meta through result.meta. call_tool_mcp also returns tool errors:
Orchestrators should read .meta and forward this evidence to the agent when the
host does not automatically surface protocol metadata.
queue_wait_ms measures only waiting for the MCP concurrency semaphore.
execution_ms measures the admitted MCP tool pipeline, including SDK HTTP work
and validation; admitted=false means that pipeline never started. duration_ms
covers the server's tool invocation, including admission checks, and excludes
model reasoning and client delivery. status is success or error for the MCP
outcome; for read_query, separately inspect metadata.completeness.
An agent can use queue_wait_ms to identify MCP admission delay, then inspect
read_query's metadata.native_stats.timeUsedMs for Pinot's native query duration
when present. Native query time overlaps execution_ms; their different timer
boundaries do not support exact network-overhead subtraction. The shared
request_id also appears in query metadata and native clientQueryId, enabling
optional history/log correlation when more context is needed.
Response timing metadata contains no secrets, principal identifiers, tool
arguments, SQL, or rows. Audit logs record the same timings with hashed principal
identifiers. MCP_MAX_RESPONSE_BYTES limits the tool payload before this bounded
timing envelope is added; it excludes the added observability metadata.
Cancellation is audit-only when no response is returned and does not prove that
Pinot execution stopped.
Incident tools are disabled until the server starts with --incident-profiles.
See the incident evidence guide and
example profile for configuration and a
workflow using begin_investigation, query_incident, optional get_trace, and
finish_investigation. Evidence queries expose the same response _meta timings
and native request IDs when reported; log access is optional. Runs are
owner-bound and budgeted; complete execution still leaves root-cause hypotheses
and dataset coverage unvalidated. This first version uses bounded in-memory state
in one process.
Pinot MCP in Action
See Pinot MCP in action below:
Fetching Metadata
Fetching Data, followed by analysis
Prompt: Can you do a histogram plot on the GitHub events against time [Pinot MCP fetching data and analyzing table]
Sample Prompts
Once Claude is running, click the hammer 🛠️ icon and try these prompts:
- Can you help me analyse my data in Pinot? Use the Pinot tool and look at the list of tables to begin with.
- Can you do a histogram plot on the GitHub events against time
Quick Start
Prerequisites
Install uv (if not already installed)
uv is a fast Python package installer and resolver, written in Rust. It's designed to be a drop-in replacement for pip with significantly better performance.
Installation
Configure Pinot Cluster
The MCP server expects a uvicorn config style .env file in the root directory to configure the Pinot cluster connection. This repo includes a sample .env.example file that assumes a pinot quickstart setup.
Configuration Reference
The server loads configuration from environment variables and from a .env file
found from the current working directory. Process environment variables take
precedence over .env, so deployment-time settings cannot be silently replaced
by a checked-out file.
Common Profiles
Pinot Connection
MCP Server
Authentication
An auth provider is required before binding HTTP or HTTPS to a non-loopback host.
Table Filtering
See SECURITY.md for the production exposure checklist and vulnerability reporting process.
Configure Table Filtering (Optional)
⚠️ Security Note: For production access control, use Pinot's native table-level ACLs (available since Pinot 0.8.0+). Table filtering in this MCP server is a convenience feature for organizing tables and improving UX, not a security boundary. It uses best-effort SQL parsing and should not be relied upon for security.
Table filtering allows you to control which Pinot tables are visible through the MCP server. This is useful for:
- Reduce Cognitive Load: Focus on relevant tables when your Pinot cluster has hundreds or thousands of tables
- Multi-Tenancy UX: Run multiple MCP server instances against the same Pinot cluster, each showing different table subsets for different teams or use cases
- Environment Separation: Deploy different MCP server instances (dev, staging, prod) that show only environment-specific tables
- Hide System Tables: Filter out internal, test, or deprecated tables from end-user view
When table filtering is enabled, all table operations are filtered to show only the configured tables.
What Gets Filtered
Table filtering applies across all MCP operations:
- Table Listing - Only configured tables appear in table lists
- Query Execution - SQL queries are checked to ensure all referenced tables (in FROM, JOIN, subqueries, CTEs, etc.) match the configured patterns
- Table Operations - Direct table access operations filter by table name:
- Get table details, size, and metadata
- Get table segments and segment metadata
- Get index/column details
- Get/update table configurations
- Schema Operations - Schema operations filter by schema name:
- Get/create/update schemas
- Create table configurations
Setup
Copy the example configuration file:
Edit table_filters.yaml to specify which tables to include:
Configure the filter file path in your .env:
Pattern Matching
The filter supports glob-style patterns using standard Unix filename pattern matching:
exact_table_name- Matches exactly this tableprefix_*- Matches all tables starting with "prefix_"*_suffix- Matches all tables ending with "_suffix"*pattern*- Matches all tables containing "pattern"sharded_table_?- Matches tables with exactly one character after the underscore (e.g.,sharded_table_1,sharded_table_a)
Query Filtering
When filtering is enabled, SQL queries are checked before execution:
- Supported SQL Features: FROM clauses, JOIN clauses (INNER, LEFT, RIGHT, OUTER, CROSS), subqueries, CTEs (WITH), and comma-separated table lists
- Quoted Identifiers: Supports both double-quoted (
"table name") and backtick-quoted (`table_name`) table names - Schema Prefixes: Handles schema-qualified table names (e.g.,
database.schema.table) - Comments: Removes SQL comments before checking
Example filtered query:
Error: Query references unauthorized tables: other_table. Allowed tables: allowed_table, prod_*
Configuration Features
Fail-Fast Validation:
- ⚠️ If
PINOT_TABLE_FILTER_FILEis configured but the file doesn't exist, the server will fail to start with aFileNotFoundError - This prevents accidentally showing all tables due to misconfiguration
- Empty filter files or missing
included_tableskey will show all tables (no filtering)
Comprehensive Filtering:
- All MCP tools that access tables apply filtering before execution
- Consistent filtering across all table access points
- Clear error messages indicate which tables don't match the configured patterns
Disabling Table Filtering
To disable table filtering, either:
- Remove the
PINOT_TABLE_FILTER_FILEenvironment variable, or - Don't configure it in your
.envfile
When not configured, all tables in the Pinot cluster are visible.
When a filter file supplies both allow_all: true and a non-empty
included_tables, the explicit allow-list takes precedence and the server logs a
warning. Applying a reload requires the token from an unchanged dry-run candidate.
Read-only Query Enforcement
The read_query tool always validates SQL before forwarding it to Pinot. It
accepts one statement only, and that statement must be a read-only SELECT or
WITH ... SELECT query. SQL comments are stripped, semicolon-stacked statements
are rejected, and write/DDL/admin keywords are blocked.
Configure OAuth Authentication (Optional)
To enable OAuth authentication, set the following environment variables in your .env file:
Required variables (when OAUTH_ENABLED=true):
OAUTH_CLIENT_ID: OAuth client IDOAUTH_CLIENT_SECRET: OAuth client secretOAUTH_BASE_URL: Your MCP server base URLOAUTH_AUTHORIZATION_ENDPOINT: OAuth authorization endpoint URLOAUTH_TOKEN_ENDPOINT: OAuth token endpoint URLOAUTH_JWKS_URI: JSON Web Key Set URI for token verificationOAUTH_ISSUER: Token issuer identifier
Optional variables:
OAUTH_AUDIENCE: audience tokens are validated against. Defaults to the canonical MCP resource URI (OAUTH_BASE_URL+MCP_PATH). Set it when your provider issues a differentaud— for example an IdP that puts the client ID there.OAUTH_GRANTED_SCOPES: Pinot scopes granted to authenticated principals (default all three). Usepinot:readto make the deployment read-only for every OIDC caller.OAUTH_REQUIRED_SCOPES: baseline scopes an access token must already carry (default: none enforced).OAUTH_EXTRA_AUTH_PARAMS: Additional authorization parameters as JSON object (e.g.,{"scope": "openid profile"})
Tool-level authorization uses pinot:read / pinot:write / pinot:admin. General-purpose OIDC providers issue a fixed scope catalog and cannot mint resource scopes like these, so OAUTH_GRANTED_SCOPES is what makes an authenticated user able to call anything — narrow it rather than leaving tools ungated.
Example configuration:
Run the server
You should see logs indicating that the server is running.
Security notes:
- STDIO is the default. When HTTP is selected it binds to
127.0.0.1; setMCP_HOST=0.0.0.0only with OAuth or static-token authentication plus TLS or an authenticated reverse proxy.- The server refuses to start when HTTP is bound to a non-loopback host without an auth provider (
AUTH_PROVIDER=oauthorstatic, or the legacyOAUTH_ENABLED=true).read_queryenforces a single read-only SQL statement before execution. This is a guardrail, not a replacement for Pinot authentication and authorization.- The supported
mcp[cli]dependency includes DNS rebinding protections for the Streamable HTTP server.- Confirmation replay state and rate-limit buckets are process-local. Run exactly one server process/Helm replica. The chart rejects
replicas != 1; horizontal scaling requires a shared state-store implementation./readyzreports MCP process readiness, not Pinot cluster health. Usetest_connectionto diagnose Pinot dependencies.
Launch Pinot Quickstart (Optional)
Start Pinot QuickStart using docker:
Query MCP Server
This quickstart just checks all the tools and queries the airlineStats table.
Claude Desktop Integration
Open Claude's config file
Add an MCP server entry
Replace /path/to/uv with the absolute path to the uv command, you can run which uv to figure it out.
Replace /path/to/mcp-pinot with the absolute path to the folder where you cloned this repo.
Note: you must use stdio transport when running your server to use with Claude desktop.
You could also configure environment variables here instead of the .env file, in case you want to connect to multiple pinot clusters as MCP servers.
Restart Claude Desktop
Claude will now auto-launch the MCP server on startup and recognize the new Pinot-based tools.
Using the MCP Bundle
The release workflow publishes a Claude Desktop MCP Bundle (.mcpb). Its UV
runtime installs the locked dependencies for the user's platform, so one small
bundle works across macOS, Linux, and Windows. To build one locally:
Open the resulting .mcpb file to install it in Claude Desktop.
Security and Vulnerability Reporting
See SECURITY.md for vulnerability reporting instructions, security categories, and the checklist for safely exposing the MCP HTTP endpoint.
Developer
- MCP tool definitions live in
mcp_pinot/server.py; Pinot HTTP/DB operations live inmcp_pinot/pinot_client.py. - See MCP SDK compatibility and migration for the dependency policy, SDK 2 integration changes, validation, and rollback.
Build
Build the project with
Test
Test the repo with:
Build the Docker image
Run the container
This uses the default STDIO transport. For HTTP/Kubernetes deployments, configure an inbound auth provider before binding to a non-loopback address; see the configuration and Helm sections above.
来源:README.md,提交 464b0ab
工具
0版本历史
3- v5.0.0最新Oct 12, 2026
- v4.1.0Oct 1, 2026
- v5.0.0-beta.1Sep 16, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分