Skip to main content
ClaudeWave

MCP server that stops an AI agent's Trino or Pinot query before it stalls your shared cluster: priced from the engine's own plan, refused with a fix the agent can act on

MCP ServersRegistry oficial0 estrellas0 forks● PythonApache-2.0Actualizado today
ClaudeWave Trust Score
95/100
✓ Verified
Passed
  • ✓Open-source license (Apache-2.0)
  • ✓Actively maintained (<30d)
  • ✓Clear description
  • ✓Topics declared
  • ✓Documented (README)
Last scanned: 10/10/2026
Install in Claude Code / Claude Desktop
Method: UVX (Python) · lagaam
Claude Code CLI
claude mcp add lagaam -- uvx lagaam
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "lagaam": {
      "command": "uvx",
      "args": ["lagaam"],
      "env": {
        "TRINO_HOST": "<trino_host>"
      }
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
Detected environment variables
TRINO_HOST
Casos de uso

Resumen de MCP Servers

![Lagaam — every query priced before it runs](docs/banner.png)

**One agent query shouldn't stall everyone's Trino.** On a shared cluster, a
missing partition filter or an accidental cross join doesn't cost you a bill —
it costs everyone else their queries. Lagaam is an MCP server that sits
between your AI agents and your lakehouse (Trino and Apache Pinot): every
query is schema-grounded, priced from the engine's own plan *before* it runs,
checked against a budget, and audited — and the bad one is refused before it
runs, with a fix the agent can act on.

![Lagaam demo: SELECT * rejected, an oversized join blocked pre-execution, a scoped query running](docs/demo.gif)

*Real session, real Trino, nothing mocked — reproduce it with
`uv run --project server python examples/demo.py`.*

![Lagaam demo: a consuming Pinot segment priced at its flush threshold, a keyless join blocked, the same join admitted on a proven upsert key](docs/demo-pinot.gif)

*Real session, real Pinot 1.5.1 realtime table, nothing mocked — reproduce it
with `uv run --project server python examples/demo_pinot.py`.*

## The problem

Agents write syntactically-valid, catastrophic SQL, and on a shared cluster
the damage isn't theirs alone. A missing partition filter turns into a full
scan that ties up every worker; an accidental cross join fills worker memory
while everyone else's queries wait behind it; a retry loop runs it again. A
`SELECT *` drags 40 columns into a context window that needed 2. The usual
fix is to not give agents database access at all.

Lagaam gives them access with reins on:

- **Cost is a quotation, not a bill.** Every query is priced from the
  engine's own plan before execution — `EXPLAIN (TYPE IO)` for the bytes it
  would scan, `EXPLAIN (TYPE LOGICAL)` for the widest row count any operator
  would build (the number a cross join blows and a `LIMIT` cannot hide).
  Over budget → blocked, with the number and the fix.
- **Un-estimable means no.** No table statistics, a self-join that breaks
  the estimate, a passthrough the planner can't see — the gate fails safe
  instead of hoping.
- **Read-only, enforced in the AST.** Single `SELECT` only. No DDL/DML, no
  multi-statement injection, no `SELECT *`, no table-function passthrough,
  and a `LIMIT` is injected when missing. Validated SQL is re-rendered, so
  what runs is exactly what was checked.
- **Agents ground themselves.** `list_catalogs` and `describe_table` return
  exact names, types, and row estimates — scoped to the agent's table grant,
  so the agent never learns names it isn't allowed to touch.
- **Results are verified before they're trusted.** Zero rows, truncated
  pages, all-NULL columns — the agent gets a warning with a next action, not
  a silently misleading answer.
- **Every call is audited.** One JSONL line per tool call: who, what,
  allowed or denied, and why.

## Doesn't Trino already limit this?

It limits a query once it is running. Lagaam refuses it before it starts.
Keep both.

| | Acts | What the agent sees | Catches a cross join that reads little |
|---|---|---|---|
| [`query.max-scan-physical-bytes`](https://trino.io/docs/current/admin/properties-query-management.html) | during execution: terminated once the bytes are scanned | a query failure | no — it counts bytes read, not rows built |
| [`query.max-execution-time`](https://trino.io/docs/current/admin/properties-query-management.html) | during execution: terminated after the time is spent | a query failure | only after it has held the cluster that long |
| [Resource groups](https://trino.io/docs/current/admin/resource-groups.html) (`hardPhysicalDataScanLimit`, `softMemoryLimit`, …) | on the *next* query: new queries queue once the group is over its share | its later queries wait | no — the running query continues |
| Lagaam | before execution, from `EXPLAIN` | a refusal with the number and the fix | yes — it prices the rows the widest step would build |

Measured on Trino 476: `SELECT o.orderkey, l.partkey FROM tpch.tiny.orders o
CROSS JOIN tpch.tiny.lineitem l LIMIT 10` reads 676,575 bytes by Trino's own
plan — any scan cap above 0.7 MB lets it run — and would build 902,625,000
rows. Lagaam refuses it before it runs: *"This query would build 902,625,000
rows at its widest step, over your budget of 50,000,000 … a LIMIT will not
help — join on a column with more distinct values, or filter each side
before the join."*

Resource groups stay your backstop for everything that does reach the
cluster; Lagaam is the gate in front of it for agent traffic.

## What about other database MCP servers?

They're good servers that do a different job: keep the agent read-only and
bound what comes back. Lagaam does that too, and also prices the query first.

| | Read-only | Row cap | Timeout | Checks the plan before running |
|---|---|---|---|---|
| [tuannvm/mcp-trino](https://github.com/tuannvm/mcp-trino) | on by default | results truncated while fetching (`TRINO_MAX_ROWS`) | during execution (`TRINO_QUERY_TIMEOUT`) | no — `explain_query` shows the agent a plan; it doesn't gate `execute_query` |
| [startreedata/mcp-pinot](https://github.com/startreedata/mcp-pinot) | always on, parsed before execution | `LIMIT` rewritten before execution, paged results | during execution (`PINOT_QUERY_TIMEOUT`, 60 s) | no |
| [bytebase/dbhub](https://github.com/bytebase/dbhub) | opt-in (`readonly`): keyword check plus the database's own read-only transaction | opt-in (`max_rows`), injected as `LIMIT`/`TOP` | opt-in (`query_timeout`), during execution | no — opt-in `explain_sql` shows a plan; it doesn't gate `execute_sql` |
| Lagaam | always on, parsed before execution | 1,000 by default; a bigger `LIMIT` is lowered before it runs | during execution (`LAGAAM_QUERY_TIMEOUT`, 300 s) | yes — scan bytes and widest-step rows from `EXPLAIN`; over budget is refused |

## Catch rate

11 queries an LLM agent plausibly writes — full scans, `SELECT *`, DDL,
injection attempts, oversized joins, out-of-grant reads. A raw MCP
wrapper submits all of them to the engine. Lagaam stops **11/11 before
execution** while the well-scoped control query runs untouched.
Reproduce: [`benchmarks/catch_rate.py`](benchmarks/catch_rate.py) →
[results](benchmarks/results.md).

## Quickstart

Against the Trino you already have (`TRINO_PORT` / `TRINO_USER` if yours
aren't `8080` / `lagaam`):

```bash
TRINO_HOST=trino.internal LAGAAM_ALLOWED_TABLES=hive.sales.orders uvx lagaam   # MCP server on stdio
```

Or try it on a demo warehouse:

```bash
git clone https://github.com/lagaam-ai/lagaam && cd lagaam
docker compose -f examples/docker-compose.yml --profile trino up -d   # demo warehouse
cd server && uv sync
LAGAAM_ALLOWED_TABLES=tpch.tiny.orders,tpch.tiny.lineitem \
  uv run python -m lagaam                                             # MCP server on stdio
```

For Pinot, `--profile pinot` brings up the batch quickstart and
`--profile pinot-realtime up -d` brings up a Kafka-fed streaming one —
run `examples/pinot-realtime/bootstrap.sh` after it to create the topics,
tables and feed. Then start the server with `LAGAAM_ENGINE=pinot`.

Wire it into any MCP client (Claude Code, Claude Desktop, or your own agent):

```json
{
  "mcpServers": {
    "lagaam": {
      "command": "uvx",
      "args": ["lagaam"],
      "env": {
        "TRINO_HOST": "localhost",
        "LAGAAM_MAX_SCAN_BYTES": "5368709120",
        "LAGAAM_ALLOWED_TABLES": "hive.sales.orders,hive.sales.customers"
      }
    }
  }
}
```

In Claude Code, install it as a plugin instead:

```
/plugin marketplace add lagaam-ai/lagaam
/plugin install lagaam@lagaam
```

It asks for the tables to allow (`LAGAAM_ALLOWED_TABLES`) and your Trino
host, port and user (`localhost` / `8080` / `lagaam` if you leave them).
From a shell, pass them as flags:

```bash
claude plugin marketplace add lagaam-ai/lagaam
claude plugin install lagaam@lagaam \
  --config allowed_tables=hive.sales.orders --config trino_host=trino.internal
```

On Pinot, pick `engine=pinot` and set the controller and broker URLs
(`http://localhost:9000` / `http://localhost:8000` if you leave them):

```bash
claude plugin install lagaam@lagaam --config engine=pinot \
  --config allowed_tables=pinot.default.baseballStats \
  --config pinot_controller_url=http://pinot.internal:9000 \
  --config pinot_broker_url=http://pinot.internal:8099
```

Other `LAGAAM_*` settings, and `PINOT_USER` / `PINOT_PASSWORD` for a Pinot
with auth, are read from the environment you start `claude` in.

The agent gets three tools — `list_catalogs`, `describe_table`,
`query_data` — and cannot reach the engine any other way.

## Configuration

| Env var | Meaning | Default |
|---|---|---|
| `LAGAAM_ALLOWED_TABLES` | Comma list of `catalog.schema.table` grants | **required** |
| `LAGAAM_ALLOW_ALL_TABLES` | `true` to run with no grant at all | off |
| `LAGAAM_AGENT_NAME` | Identity stamped on the audit trail | `anonymous` |
| `LAGAAM_MAX_SCAN_BYTES` | Scan-bytes budget per query, pre-execution | 50 GiB |
| `LAGAAM_MAX_ROWS` | Scanned-row estimate budget per query | ungated |
| `LAGAAM_MAX_INTERMEDIATE_ROWS` | Rows the engine would *build* at its widest step — not rows returned, so a `LIMIT` doesn't lower it | 50,000,000 |
| `LAGAAM_MAX_RETURNED_ROWS` | Rows returned to the agent per query — unset, the server applies its own 1000-row cap, and a bigger `LIMIT` in the query is lowered to it before it runs | `1000` (max `100000`) |
| `LAGAAM_QUERY_TIMEOUT` | Wall-clock seconds per query | `300` |
| `LAGAAM_METADATA_TTL` | Metadata cache TTL, seconds | `300` |
| `LAGAAM_AUDIT_LOG` | Audit JSONL file path | stderr |
| `TRINO_HOST` / `TRINO_PORT` / `TRINO_USER` | Trino coordinator | `localhost` / `8080` / `lagaam` |

**The server will not start without `LAGAAM_ALLOWED_TABLES`.** An agent that
can reach every table in every catalog is the thing this exists to prevent, so
that has to be asked for — set `LAGAAM_ALLOW_ALL_TABLES=true` if you mean it.

**The budget dimensions above apply whethe
ai-agentsapache-pinotdata-engineeringlakehousellmllm-toolsmcpmcp-servermodel-context-protocolpythonsqltrino

Lo que la gente pregunta sobre lagaam

¿Qué es lagaam-ai/lagaam?

+

lagaam-ai/lagaam es mcp servers para el ecosistema de Claude AI. MCP server that stops an AI agent's Trino or Pinot query before it stalls your shared cluster: priced from the engine's own plan, refused with a fix the agent can act on Tiene 0 estrellas en GitHub y su última actualización registrada es del 2026-10-09.

¿Cómo se instala lagaam?

+

Puedes instalar lagaam clonando el repositorio (https://github.com/lagaam-ai/lagaam) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.

¿Es seguro usar lagaam-ai/lagaam?

+

Nuestro agente de seguridad ha analizado lagaam-ai/lagaam y le ha asignado un Trust Score de 95/100 (tier: Verified). Revisa el desglose completo de comprobaciones superadas y flags en esta página.

¿Quién mantiene lagaam-ai/lagaam?

+

lagaam-ai/lagaam es mantenido por lagaam-ai. La última actividad registrada en GitHub es del 2026-10-09, con 0 issues abiertos.

¿Hay alternativas a lagaam?

+

Sí. En ClaudeWave puedes explorar mcp servers similares en /categories/mcp, ordenados por popularidad o actividad reciente.

Despliega lagaam en tu cloud

Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.

¿Mantienes este repo? Añade un badge a tu README

Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.

Featured on ClaudeWave: lagaam-ai/lagaam
[![Featured on ClaudeWave](https://claudewave.com/api/badge/lagaam-ai-lagaam)](https://claudewave.com/repo/lagaam-ai-lagaam)
<a href="https://claudewave.com/repo/lagaam-ai-lagaam"><img src="https://claudewave.com/api/badge/lagaam-ai-lagaam" alt="Featured on ClaudeWave: lagaam-ai/lagaam" width="320" height="64" /></a>

Más MCP Servers

Alternativas a lagaam