# Apache Pinot MCP Server (oci · ghcr.io/startreedata/mcp-pinot)

Query and manage Apache Pinot through MCP with typed tools and preview-first safety.

- Trust score: 50/100 (low)
- Change this week: +3
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-11-05

## Components

- oci · `ghcr.io/startreedata/mcp-pinot`: 50/100 (this document), [markdown](https://verifymcp.io/servers/startreedata-mcp-pinot/ghcr-io-startreedata-mcp-pinot.md), [page](https://verifymcp.io/servers/startreedata-mcp-pinot/ghcr-io-startreedata-mcp-pinot)
- pypi · `mcp-pinot-server`: 82/100, [markdown](https://verifymcp.io/servers/startreedata-mcp-pinot/mcp-pinot-server.md), [page](https://verifymcp.io/servers/startreedata-mcp-pinot/mcp-pinot-server)

## Channel facts

- Registry: `oci`
- Package: `ghcr.io/startreedata/mcp-pinot`
- Version: `5.0.0`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-11-05.

- **Supply Chain Security**: 0/100
  - No malware scan is available for this kind of package: the supply-chain vendors we use do not cover it. This is a permanent gap in our coverage, not a finding about the package.
  - Known CVEs could not be checked: this artifact ships no SBOM or dependency manifest, so there is no dependency list to read.
  - Install-script risk not yet assessed.
  - Dependency health could not be checked: this artifact ships no SBOM or dependency manifest, so there is no dependency list to read.
- **Provenance & Transparency**: 48/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - Clear OSI-approved license (Apache-2.0).
  - Actively maintained (last published 24 days ago).
  - Publishes a security disclosure policy (SECURITY.md).
- **Schema Quality & AI Usability**: 79/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 3315 tokens (~174/item across 19 items; 18 tools + 1 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 63/100
  - Stability observed for 19 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 92/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 71% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 18 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 20 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a current MCP spec version (2026-07-28).

**Unverified: 1 category.** A category scored 0 because we could not verify it: a data source with nothing on this package, evidence we could not reach, or a check we could not run. We only credit what we can confirm.

## Install

### How do I install the Apache Pinot MCP Server server?

Apache Pinot MCP Server runs locally as a container image, launched with docker run --rm -i ghcr.io/startreedata/mcp-pinot:5.0.0. Ready-made configuration for Claude, Cursor, VS Code, Codex and 3 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add startreedata-mcp-pinot -- docker run --rm -i ghcr.io/startreedata/mcp-pinot:5.0.0
```

### Cursor

```json
{
  "mcpServers": {
    "startreedata-mcp-pinot": {
      "command": "docker",
      "args": [
        "run",
        "--rm",
        "-i",
        "ghcr.io/startreedata/mcp-pinot:5.0.0"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "startreedata-mcp-pinot": {
      "command": "docker",
      "args": [
        "run",
        "--rm",
        "-i",
        "ghcr.io/startreedata/mcp-pinot:5.0.0"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add startreedata-mcp-pinot -- docker run --rm -i ghcr.io/startreedata/mcp-pinot:5.0.0
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "startreedata-mcp-pinot": {
      "type": "local",
      "command": [
        "docker",
        "run",
        "--rm",
        "-i",
        "ghcr.io/startreedata/mcp-pinot:5.0.0"
      ],
      "enabled": true
    }
  }
}
```

### Hermes

```yaml
mcp_servers:
  startreedata-mcp-pinot:
    command: "docker"
    args: ["run", "--rm", "-i", "ghcr.io/startreedata/mcp-pinot:5.0.0"]
```

### Netclaw

```json
{
  "McpServers": {
    "startreedata-mcp-pinot": {
      "Transport": "stdio",
      "Command": "docker",
      "Arguments": [
        "run",
        "--rm",
        "-i",
        "ghcr.io/startreedata/mcp-pinot:5.0.0"
      ]
    }
  }
}
```

### Other

```json
{
  "mcpServers": {
    "startreedata-mcp-pinot": {
      "command": "docker",
      "args": [
        "run",
        "--rm",
        "-i",
        "ghcr.io/startreedata/mcp-pinot:5.0.0"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-11-04 (score 50, +1)

No change was recorded against any check on this day. Stability & Change Management went from 57 to 60. That category is still filling its 30-day observation window: 17 days of observed history at the previous scan, 18 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-11-02 (score 49, +1)

No change was recorded against any check on this day. Stability & Change Management went from 50 to 53. That category is still filling its 30-day observation window: 15 days of observed history at the previous scan, 16 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-31 (score 48, +1)

No change was recorded against any check on this day. Stability & Change Management went from 43 to 47. That category is still filling its 30-day observation window: 13 days of observed history at the previous scan, 14 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-29 (score 47, +1)

No change was recorded against any check on this day. Stability & Change Management went from 37 to 40. That category is still filling its 30-day observation window: 11 days of observed history at the previous scan, 12 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-27 (score 46, +1)

No change was recorded against any check on this day. Stability & Change Management went from 30 to 33. That category is still filling its 30-day observation window: 9 days of observed history at the previous scan, 10 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-25 (score 45, +1)

No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-22 (score 44, +1)

No change was recorded against any check on this day. Stability & Change Management went from 13 to 17. That category is still filling its 30-day observation window: 4 days of observed history at the previous scan, 5 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-20 (score 43, +1)

No change was recorded against any check on this day. Stability & Change Management went from 7 to 10. That category is still filling its 30-day observation window: 2 days of observed history at the previous scan, 3 at this one. The score rises as the window fills, whether or not the server changes.

## MCP tools (18)

### `test_connection` (~91 tokens)

Test connection

Probe Pinot connectivity and return diagnostics.

Runs three checks — broker connection, a trivial ``SELECT 1`` query, and a
controller table listing — and reports which succeeded plus a small sample of
tables. Useful for troubleshooting configuration before using other tools.

Failure recovery:
Individual check failures are returned in ``error``. Verify the broker and
controller URLs, credentials, and network, then retry only failed checks.

Output parameters:

- `connection_test` (boolean): True when the broker answered, i.e. the query check below succeeded.
- `dbapi_test` (boolean): Informational: True when the optional pinotdb DB-API probe also succeeded. No tool uses that path, so false here does not mean the deployment is unhealthy — check query_test and tables_test instead.
- `error`: Names the checks that failed, or null when both required checks passed.
- `query_test` (boolean): True when a trivial 'SELECT 1' succeeded through the same broker path read_query uses.
- `sample_tables` (array): Up to five example table names.
- `tables_count`: Number of tables discovered, when available.
- `tables_test` (boolean): True when the controller table listing succeeded.

### `reload_table_filters` (~225 tokens)

Reload table filters

Preview or apply the configured table-filter YAML without restarting.

Reads only the path configured by ``PINOT_TABLE_FILTER_FILE``. The YAML must be
an object whose ``included_tables`` value is a non-empty list of glob strings.
Allowing every table requires an explicit ``allow_all: true``. The default
\``dry_run=true`` validates and reports the before/after patterns and returns a
short-lived confirmation token. Pass ``dry_run=false`` with that token to apply
the exact candidate atomically. Editing the file after preview invalidates the
confirmation and requires another preview.

Failure recovery:
A missing setting/file or malformed YAML is non-retryable until corrected;
fix ``PINOT_TABLE_FILTER_FILE`` or its ``included_tables`` list, then retry.

Input parameters:

- `confirmation_token`: One-time token returned by a dry-run preview of the exact current filter-file contents. Required when dry_run is false.
- `dry_run` (boolean): When true (default), validate and preview the candidate allow-list without changing server state. Pass false explicitly to apply it.

Output parameters:

- `applied` (boolean): True only when the in-memory allow-list was changed.
- `confirmation_token`: Short-lived token bound to this exact filter preview; required to apply.
- `message` (string): Human-readable summary of the reload.
- `new_filter_count` (integer): Number of allowed tables after the reload.
- `new_filters`: Validated candidate patterns; null means all tables.
- `previous_filter_count` (integer): Number of allowed tables before the reload.
- `previous_filters`: Allow-list patterns active before the operation; null means all.
- `status` (string): Whether the candidate filters were previewed, applied, or failed.

### `begin_investigation` (~108 tokens)

Begin investigation

Open an owner-bound, budgeted evidence run using a server-owned profile.

Supply closed baseline/incident windows in epoch milliseconds. The server
checks scope, windows, and authorization before issuing an opaque run ID.
Failure recovery:
Correct invalid scope/window inputs; expired runs require a new investigation.

Input parameters:

- `baseline_start_ms` (integer, required)
- `end_ms` (integer, required)
- `profile_id` (string, required)
- `service` (string, required)
- `start_ms` (integer, required)

Output parameters:

- `baseline_start_ms` (integer)
- `deadline_seconds` (integer)
- `end_ms` (integer)
- `max_queries` (integer)
- `profile_id` (string)
- `run_id` (string)
- `scope` (string)
- `service` (string)
- `start_ms` (integer)

### `query_incident` (~101 tokens)

Query incident

Collect bounded evidence with fixed tenant/time predicates and citations.

The server generates SQL for the selected kind. Candidate filters apply only
to onset queries. Failed, unknown, partial, truncated, or late execution is
retained as incomplete evidence; it cannot support a qualified finish.
Failure recovery:
Query attempts consume budget even on failure. Inspect evidence before retrying.

Input parameters:

- `candidate`
- `kind` (string, required)
- `run_id` (string, required)

Output parameters:

- `columns` (array)
- `complete` (boolean)
- `dataset_coverage_attested` (boolean)
- `error`
- `evidence_id` (string)
- `kind` (string)
- `metadata` (object): Native execution evidence, independently of paging or dataset coverage.
- `rows` (array)
- `run_id` (string)
- `sha256` (string)
- `sql` (string)

### `get_trace` (~77 tokens)

Get trace

Retrieve scoped trace rows with actual span and parent-span identifiers.

Configure both span columns in the server profile. This fetches recorded
relationships and does not infer causality or validate instrumentation coverage.
Failure recovery:
Use an exact scoped trace ID; inspect completeness before citing.

Input parameters:

- `run_id` (string, required)
- `trace_id` (string, required)

Output parameters:

- `columns` (array)
- `complete` (boolean)
- `dataset_coverage_attested` (boolean)
- `error`
- `evidence_id` (string)
- `kind` (string)
- `metadata` (object): Native execution evidence, independently of paging or dataset coverage.
- `rows` (array)
- `run_id` (string)
- `sha256` (string)
- `sql` (string)

### `finish_investigation` (~250 tokens)

Finish investigation

Close a run once with authentic citations and an unverified outcome.

Choose proposed for an adequately supported candidate association, abstained
when adequate evidence shows healthy, unrelated, or confounded observations,
and incomplete when missing, sparse, stale, partial, or failed evidence prevents
evaluating the association. Complete SQL execution can still yield insufficient
observations. Missing matched controls in otherwise adequate observations can
reveal confounding and support abstention.

Proposed requires a hypothesis; proposed/abstained require complete citations.
Incomplete requires a reason. Pending work blocks finishing. These semantic
choices are caller judgments; finishing validates ownership, citations, and
execution completeness. Evidence sufficiency, the semantic choice, hypotheses,
and dataset coverage remain unvalidated.
Failure recovery:
Correct citation/status errors; a closed run cannot be reused.

Input parameters:

- `citations` (array, required)
- `hypothesis`
- `reason`
- `run_id` (string, required)
- `status` (string): Caller decision: proposed for an adequately supported unverified association; abstained for adequate evidence showing healthy, unrelated, or confounded observations; incomplete when required coverage…

Output parameters:

- `citations` (object)
- `confirmed_cause` (boolean)
- `dataset_coverage_attested` (boolean)
- `failed_evidence_ids` (array)
- `hypothesis`
- `hypothesis_validated` (boolean)
- `query_count` (integer)
- `reason`
- `run_id` (string)
- `scope` (string)
- `status` (string)

### `read_query` (~273 tokens)

Read query

Run a read-only SQL query against Pinot and return a page of rows.

Only a single SELECT (or WITH ... SELECT) statement is allowed; the query is
rejected if it contains multiple statements or write/DDL/admin keywords.
Results are paginated to keep responses small — use ``limit``/``offset`` and
the ``has_more`` flag to page through large result sets.

Returns ``QueryResult`` with the page of rows, the column list, fetched row
count, a ``has_more`` flag, and native execution metadata. Missing native
metadata is unknown; complete execution does not establish dataset coverage.

Failure recovery:
SQL/allow-list/permission failures require correcting the query or access;
do not retry unchanged. A timeout or connection failure can be retried after
\``test_connection`` succeeds. Check ``metadata.completeness`` even for
zero rows; no response is promoted to healthy empty evidence.

Input parameters:

- `limit` (integer): Maximum rows to return in this page.
- `offset` (integer): Zero-based row offset for pagination.
- `query` (string, required): A single read-only statement in Pinot SQL: 'SELECT ...' or 'WITH ... SELECT ...'. Stacked statements and DML/DDL/admin keywords (INSERT, UPDATE, DELETE, DROP, SET, ...) are rejected.

Output parameters:

- `columns` (array): Column names, in result order.
- `has_more` (boolean): True when more fetched rows remain beyond this page (not necessarily more rows in the underlying table).
- `metadata` (object): Execution evidence; complete execution does not imply dataset coverage.
- `offset` (integer): Zero-based index of the first returned row.
- `row_count` (integer): Number of rows returned in this page.
- `rows` (array): Rows in this page; each row maps column name to value.
- `total_rows` (integer): Rows the query returned before this page was sliced. Pinot may have already applied its own LIMIT, so this is rows fetched, not the table total.
- `truncated` (boolean): True when the server-enforced fetch bound truncated the result.

### `list_tables` (~111 tokens)

List tables

List Pinot tables visible to this server (subject to table filters).

Returns a paginated list of table names. Use ``limit``/``offset`` and the
\``has_more`` flag to page through clusters with many tables.

Failure recovery:
An empty page is success. For authentication/connectivity errors, verify the
controller with ``test_connection`` and retry after access is restored.

Input parameters:

- `limit` (integer): Maximum tables to return in this page.
- `offset` (integer): Zero-based offset for pagination.

Output parameters:

- `has_more` (boolean): True when more tables remain beyond this page.
- `offset` (integer): Zero-based index of the first returned table.
- `table_count` (integer): Number of tables in this page.
- `tables` (array): Table names in this page.
- `total_tables` (integer): Total tables visible to this server.

### `get_table_size` (~203 tokens)

Table size details

Get a table's storage footprint: reported vs. estimated size in bytes.

Use this for capacity/size questions about a whole table. It does NOT list
segments (use ``list_segments``) or return row counts/time boundaries (use
\``list_segment_metadata``). ``reportedSizeInBytes`` is what the servers
currently hosting the segments report; ``estimatedSizeInBytes`` assumes every
replica is present.

Failure recovery:
For not-found errors, copy an exact name from ``list_tables``. Fix permission
errors before retrying; retry transient controller failures after a health
check.

Input parameters:

- `table_name` (string, required): Exact Pinot table name, without _OFFLINE/_REALTIME. Use letters, digits, hyphens, or underscores, optionally prefixed by one 'database.' qualifier; whitespace is invalid and '__' is reserved by Pinot…

Output parameters:

- `estimatedSizeInBytes`: Estimated size assuming every replica is present, in bytes.
- `reportedSizeInBytes`: Size reported by the servers currently hosting the table's segments, in bytes.
- `tableName`: The table name.

### `list_segments` (~261 tokens)

List segments

List a table's segment names, grouped by table type (OFFLINE/REALTIME).

Use this to discover segment names — e.g. to get a ``segment_name`` for
\``get_segment_index_metadata``, or to see how a table is partitioned. For
per-segment row counts / sizes / time boundaries call
\``list_segment_metadata`` instead; for total storage call ``get_table_size``.

Segment names are paginated (a busy table can have thousands) — use
\``limit``/``offset`` and the ``has_more`` flag to page through them.

Failure recovery:
An empty page is success. For not-found errors, use an exact name from
\``list_tables``; correct access errors, or retry transient controller errors.

Input parameters:

- `limit` (integer): Maximum segment names to return in this page.
- `offset` (integer): Zero-based offset for pagination.
- `table_name` (string, required): Exact Pinot table name, without _OFFLINE/_REALTIME. Use letters, digits, hyphens, or underscores, optionally prefixed by one 'database.' qualifier; whitespace is invalid and '__' is reserved by Pinot…

Output parameters:

- `OFFLINE`: OFFLINE segment names in this page, when present.
- `REALTIME`: REALTIME segment names in this page, when present.
- `has_more`: True when more segments remain beyond this page.
- `offset`: Zero-based offset of the first segment in this page.
- `returned_segments`: Number of segment names returned in this page.
- `total_segments`: Total segments across all types before paging.

### `get_segment_index_metadata` (~259 tokens)

Index/column details

Get per-column index metadata for ONE segment (which indexes each column has).

Use this to inspect how a specific segment is indexed (inverted, sorted, range,
etc.). Requires a ``segment_name`` from ``list_segments``. For a segment's row
count/size/time boundaries use ``list_segment_metadata``; for the table's
declared index *configuration* (not per-segment state) use ``get_table_config``.

Failure recovery:
A missing segment is non-retryable with the same value; refresh
\``list_segments`` and use an exact returned name. Retry transient controller
errors after ``test_connection`` succeeds.

Input parameters:

- `segment_name` (string, required): Exact, case-sensitive opaque segment name returned by list_segments; do not construct, trim, or add a table-type suffix. Pinot defines the length and characters, so this client only requires non-empt…
- `table_name` (string, required): Exact Pinot table name, without _OFFLINE/_REALTIME. Use letters, digits, hyphens, or underscores, optionally prefixed by one 'database.' qualifier; whitespace is invalid and '__' is reserved by Pinot…

Output parameters:

- `columns`: Per-column metadata for the segment, when present.
- `indexes`: Per-column index metadata (index types present on each column).

### `list_segment_metadata` (~211 tokens)

Segment metadata

Get a deterministic page of segment rows, sizes, and time boundaries.

Pinot can return thousands of segment objects. Results are sorted by exact
segment name, then sliced with ``limit``/``offset``; follow ``has_more`` until
false. Use ``list_segments`` when only names are needed.

Failure recovery:
An empty page is success. For not-found errors, use ``list_tables``;
correct permissions before retrying, and retry transient server failures
only after ``test_connection`` succeeds.

Input parameters:

- `limit` (integer): Maximum segment metadata objects in this page.
- `offset` (integer): Zero-based segment offset for pagination.
- `table_name` (string, required): Exact Pinot table name, without _OFFLINE/_REALTIME. Use letters, digits, hyphens, or underscores, optionally prefixed by one 'database.' qualifier; whitespace is invalid and '__' is reserved by Pinot…

Output parameters:

- `has_more` (boolean): True when more fetched segment metadata remains after this page.
- `offset` (integer): Zero-based index of the first returned segment.
- `returned_segments` (integer): Number of segment metadata objects in this page.
- `segments` (object): Metadata keyed by exact segment name. Values can include row counts, sizes, time boundaries, and column/index details returned by Pinot.
- `total_segments` (integer): Total segment metadata objects fetched before paging.

### `create_schema` (~151 tokens)

Create schema

Preview or create a new Pinot schema without replacing an existing schema.

The default preview performs strict local structural validation and returns a
short-lived confirmation token bound to the exact normalized schema. Pass that
token with ``dry_run=false`` to apply. Replacement belongs in ``update_schema``.

Failure recovery:
Invalid JSON, missing ``schemaName``, and controller validation failures are
non-retryable until corrected. Permission failures require access changes;
retry transient controller failures only after connectivity is restored.

Input parameters:

- `confirmation_token`: Token returned by a preview of this exact payload.
- `dry_run` (boolean): Preview safely (default); false requests application.
- `schema` (object, required): Structured Pinot schema. schemaName is required.

Output parameters:

- `applied` (boolean): True only when Pinot accepted a mutating request.
- `confirmation_token`: Short-lived token bound to this exact preview; required to apply it.
- `dry_run` (boolean): True when no mutation was sent to Pinot.
- `message`: Human-readable detail, when provided.
- `operation` (string): Stable operation identifier.
- `resource_name` (string): Exact schema or table name targeted.
- `resource_type` (string): Kind of Pinot resource targeted by the operation.
- `response_summary`: Sanitized summary returned by the Pinot controller.
- `status` (string): Whether the operation was previewed, applied, or rejected.
- `verification_tool` (string): Read tool to call after a successful mutation.
- `warnings` (array): Safety or validation warnings.

### `update_schema` (~199 tokens)

Update schema

Update an existing Pinot schema.

Accepts a typed schema object. This can change column definitions on a live
table; the default ``dry_run=true`` previews without applying and returns a
confirmation token bound to the exact replacement.

Failure recovery:
Invalid JSON/name or schema validation failures require a corrected payload;
do not retry unchanged. Fix permission errors first, and retry transient
controller failures only after connectivity is restored.

Input parameters:

- `confirmation_token`: Token returned by a preview of this exact payload.
- `dry_run` (boolean): Preview safely (default); false requests application.
- `reload` (boolean): Reload affected segments after updating.
- `schema` (object, required): Complete replacement schema; schemaName must match.
- `schema_name` (string, required): Exact Pinot schema name. It normally matches the table name without an _OFFLINE/_REALTIME suffix; use letters, digits, hyphens, or underscores, optionally prefixed by one 'database.' qualifier.

Output parameters:

- `applied` (boolean): True only when Pinot accepted a mutating request.
- `confirmation_token`: Short-lived token bound to this exact preview; required to apply it.
- `dry_run` (boolean): True when no mutation was sent to Pinot.
- `message`: Human-readable detail, when provided.
- `operation` (string): Stable operation identifier.
- `resource_name` (string): Exact schema or table name targeted.
- `resource_type` (string): Kind of Pinot resource targeted by the operation.
- `response_summary`: Sanitized summary returned by the Pinot controller.
- `status` (string): Whether the operation was previewed, applied, or rejected.
- `verification_tool` (string): Read tool to call after a successful mutation.
- `warnings` (array): Safety or validation warnings.

### `get_schema` (~148 tokens)

Get schema

Get one Pinot schema, including dimensions, metrics, time, and primary keys.

This is a single-object lookup, not a list, so pagination does not apply. The
output preserves additional fields introduced by the connected Pinot version.

Failure recovery:
For not-found errors, pass the table's exact schema name (normally the table
name without a type suffix). Fix permissions before retrying; retry transient
controller failures after ``test_connection`` succeeds.

Input parameters:

- `schema_name` (string, required): Exact Pinot schema name. It normally matches the table name without an _OFFLINE/_REALTIME suffix; use letters, digits, hyphens, or underscores, optionally prefixed by one 'database.' qualifier.

Output parameters:

- `dateTimeFieldSpecs`: Date/time column specifications.
- `dimensionFieldSpecs`: Dimension (attribute) column specifications.
- `metricFieldSpecs`: Metric (aggregatable measure) column specifications.
- `primaryKeyColumns`: Primary key columns, for upsert-enabled tables.
- `schemaName`: The schema name.

### `create_table_config` (~133 tokens)

Create table config

Create a new Pinot table configuration.

Accepts a typed table-config object. The default ``dry_run=true`` asks Pinot
to validate the payload and returns a confirmation token without applying.

Failure recovery:
Invalid JSON, missing ``tableName``, and controller validation failures need
a corrected payload; do not retry unchanged. Fix access failures first, and
retry transient controller errors after connectivity is restored.

Input parameters:

- `confirmation_token`: Token returned by a preview of this exact payload.
- `dry_run` (boolean): Preview safely (default); false requests application.
- `table_config` (object, required): Complete structured Pinot table configuration.

Output parameters:

- `applied` (boolean): True only when Pinot accepted a mutating request.
- `confirmation_token`: Short-lived token bound to this exact preview; required to apply it.
- `dry_run` (boolean): True when no mutation was sent to Pinot.
- `message`: Human-readable detail, when provided.
- `operation` (string): Stable operation identifier.
- `resource_name` (string): Exact schema or table name targeted.
- `resource_type` (string): Kind of Pinot resource targeted by the operation.
- `response_summary`: Sanitized summary returned by the Pinot controller.
- `status` (string): Whether the operation was previewed, applied, or rejected.
- `verification_tool` (string): Read tool to call after a successful mutation.
- `warnings` (array): Safety or validation warnings.

### `update_table_config` (~212 tokens)

Update table config

Update an existing Pinot table configuration.

Accepts a typed replacement table-config object. This changes a live table;
the default ``dry_run=true`` asks Pinot to validate it, compares it with the
current configuration, and returns a token without applying.

Failure recovery:
Invalid JSON/name or controller validation failures require a corrected
payload; do not retry unchanged. Fix access errors first, and retry transient
controller failures only after connectivity is restored.

Input parameters:

- `confirmation_token`: Token returned by a preview of this exact payload.
- `dry_run` (boolean): Preview safely (default); false requests application.
- `table_config` (object, required): Complete replacement table configuration.
- `table_name` (string, required): Exact Pinot table name, without _OFFLINE/_REALTIME. Use letters, digits, hyphens, or underscores, optionally prefixed by one 'database.' qualifier; whitespace is invalid and '__' is reserved by Pinot…

Output parameters:

- `applied` (boolean): True only when Pinot accepted a mutating request.
- `confirmation_token`: Short-lived token bound to this exact preview; required to apply it.
- `dry_run` (boolean): True when no mutation was sent to Pinot.
- `message`: Human-readable detail, when provided.
- `operation` (string): Stable operation identifier.
- `resource_name` (string): Exact schema or table name targeted.
- `resource_type` (string): Kind of Pinot resource targeted by the operation.
- `response_summary`: Sanitized summary returned by the Pinot controller.
- `status` (string): Whether the operation was previewed, applied, or rejected.
- `verification_tool` (string): Read tool to call after a successful mutation.
- `warnings` (array): Safety or validation warnings.

### `get_table_config` (~191 tokens)

Get table config

Get one table's indexing, retention, tenant, and ingestion configuration.

This is a single-object lookup, not a list, so pagination does not apply. Set
\``table_type`` only when one side of a hybrid table is needed.

Failure recovery:
For not-found errors, use an exact name from ``list_tables`` and a valid
table type. Fix permissions before retrying; retry transient controller
failures after ``test_connection`` succeeds.

Input parameters:

- `table_name` (string, required): Exact Pinot table name, without _OFFLINE/_REALTIME. Use letters, digits, hyphens, or underscores, optionally prefixed by one 'database.' qualifier; whitespace is invalid and '__' is reserved by Pinot…
- `table_type`: Restrict to one table type; omit to return both when present.

Output parameters:

- `offline`: OFFLINE configuration, when present/requested.
- `realtime`: REALTIME configuration, when present/requested.
- `table_name` (string): Base table name requested by the caller.

## Diagnostics

Captured diagnostic sections: Provenance. The full working is on the page: https://verifymcp.io/servers/startreedata-mcp-pinot/ghcr-io-startreedata-mcp-pinot#diagnostics

## Score history

- 2026-11-05: 50
- 2026-11-04: 50
- 2026-11-03: 49
- 2026-11-02: 49
- 2026-11-01: 48
- 2026-10-31: 48
- 2026-10-30: 47
- 2026-10-29: 47
- 2026-10-28: 46
- 2026-10-27: 46
- 2026-10-26: 45
- 2026-10-25: 45
- 2026-10-24: 44
- 2026-10-23: 44
- 2026-10-22: 44
- 2026-10-21: 43
- 2026-10-20: 43
- 2026-10-19: 42
- 2026-10-18: 42
- 2026-10-17: 41
- 2026-10-16: 10
- 2026-10-15: 10
- 2026-10-14: 10
- 2026-10-13: 10
- 2026-10-12: 10

## Common questions

### What is the Apache Pinot MCP Server server?

Apache Pinot MCP Server is listed in the public MCP registry as io.github.startreedata/mcp-pinot. Query and manage Apache Pinot through MCP with typed tools and preview-first safety. This page covers its container image (ghcr.io/startreedata/mcp-pinot).

### Is the Apache Pinot MCP Server server safe to use?

Apache Pinot MCP Server scores 50 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the Apache Pinot MCP Server server expose?

Apache Pinot MCP Server exposes 18 tools: test_connection, reload_table_filters, begin_investigation, query_incident, get_trace, and 13 more. Their descriptions and schemas cost roughly 3,204 tokens of context every time the server is loaded.

### Is the Apache Pinot MCP Server server still maintained?

Apache Pinot MCP Server is still listed as active in the MCP registry. We last reached this channel on 5 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the Apache Pinot MCP Server server under?

Apache Pinot MCP Server declares the Apache-2.0 licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- GitHub Container Registry: https://ghcr.io/startreedata/mcp-pinot
- Repository: https://github.com/startreedata/mcp-pinot
- Website: https://startreedata.github.io/mcp-pinot/
- Changelog RSS feed: https://verifymcp.io/servers/startreedata-mcp-pinot/ghcr-io-startreedata-mcp-pinot.xml
- Changelog JSON feed: https://verifymcp.io/servers/startreedata-mcp-pinot/ghcr-io-startreedata-mcp-pinot.json
- HTML version of this page: https://verifymcp.io/servers/startreedata-mcp-pinot/ghcr-io-startreedata-mcp-pinot
