Skip to main content
Glama

Grane

The open-source analytics harness for AI agents.

Agents reason. Grane executes.

Your AI can write SQL. That doesn't mean it knows what Revenue means.

Agent → MCP → Grane → Warehouse
  • Deterministic business metrics

  • Safe joins and grain

  • Governed + exploratory analytics

  • Works with existing semantic definitions

  • No LLM inside Grane

  • Fully self-hosted

Why did revenue fall last month?

Try it

Requires Node 20+. No Docker. No API keys for Grane.

From a git clone (until 0.7.0 is on npm), one guided command:

git clone https://github.com/Nareik33L/grane.git
cd grane
npm install
npm run setup

That walks you through: demo shop or your own warehouse (any connector Grane already supports) → write/validate project config → register Cursor / Claude / another MCP client → a question to ask the agent. Type back to return to the previous step. Prompts are the default. CI / scripts can skip them:

npm run setup -- --yes --path demo --connect cursor
npm run setup -- --yes --path own --url postgres://readonly@host:5432/db --offline --skip-connect

npm run demo still builds the shop and runs the investigation without the wizard. Once grane-analytics@0.7.0 is published, the same paths are npx grane-analytics setup and npx grane-analytics demo.

On the demo path you should see: revenue down ~14%, Germany the outlier, card authentication failures the lead. Then ask:

Why did Revenue fall last month?

The demo writes a DuckDB connection into the project it just built. Query that same project — no Postgres, no Docker:

npx tsx src/cli/index.ts -p demo/analytics query revenue --last last_month

From a clone, npx grane-analytics is npx tsx src/cli/index.ts until you npm run build and use node dist/cli/index.js.

Postgres (optional):

docker compose up

Demo project: demo/. Questions: demo/questions.md.


Related MCP server: FastAPI Database MCP Server

Why Grane exists

AI agents can already write SQL. Your database does not know the approved definition of Revenue — and letting an LLM invent it produces plausible-looking, wrong numbers.

Grane sits between the warehouse and the agent. The agent sends intent (revenue by country, period: last_month). Grane resolves the definition, plans joins, compiles SQL, and executes it read-only. Permitted raw columns can be explored without writing SQL, and every result is labelled governed, mixed, or exploratory.

If Grane cannot safely resolve the meaning, it refuses. That is a feature.

Connect Claude, ChatGPT, Gemini, Cursor, or any MCP agent. Grane does not need their API keys.

Walkthrough: docs/connect-an-agent.md · MCP tools: docs/mcp-setup.md · Your own Postgres: docs/first-week.md

Install (your warehouse)

npm install -g grane-analytics
grane init
export DATABASE_URL=postgres://readonly_user:...@host:5432/db
grane discover --write-relationships
grane validate
grane validate --production
grane certify --engine postgres
grane mcp connect cursor

Use a read-only database user — that role is the real control. Grane refuses write-headed SQL on every warehouse and honours limits.timeout_ms. Postgres and Redshift wrap each query in a READ ONLY transaction with statement_timeout. DuckDB file connections open with access_mode: READ_ONLY. MySQL sets SESSION TRANSACTION READ ONLY. ClickHouse sends readonly=1. Snowflake, BigQuery, and Databricks rely on the warehouse role plus the write-keyword guard.

Architecture

Claude / ChatGPT / Cursor / internal agents
                 |
                 |  MCP
                 v
              GRANE          metrics, dimensions, relationships,
                 |           deterministic compiler, validation,
                 |  SQL      join/grain safety, provenance
                 v
           Your warehouse

Four MCP tools: catalog, query, validate, explain. Agents send analytical intent, not SQL.

{
  "metrics": ["revenue"],
  "dimensions": ["country"],
  "raw_dimensions": ["orders.discount_code"],
  "time": { "period": "last_month" }
}

trust

Meaning

governed

Approved definitions only. Present as business truth.

mixed

Approved metrics plus permitted raw fields. A lead, not approved truth.

exploratory

Raw warehouse data only. Investigation, not governed analytics.

Benchmark

Same shop, same questions, three ways — no LLM in the loop. 50 questions. Paths A and B are representative SQL fixtures, not live model samples. Grane compiled the same request five times: identical SQL.

Numeric

Refusal

Permission

Overall

A Direct DB MCP

31%

72%

0%

47%

B DB MCP + SKILL.md

94%

90%

100%

91%

C Grane

100%

100%

100%

100%

A well-written SKILL.md gets definitions right. It still writes fan-out joins and cannot enforce a PII denylist. Grane compiles the join plan and refuses the rest. If live agents beat these fixtures, that is useful — publish it.

npm run test:benchmark

Methodology: tests/benchmark/README.md.

Warehouses and semantic providers

Postgres is bundled. Other engines are optional installs. Certified in CI: PostgreSQL 16, MySQL 8, DuckDB 1.5, and ClickHouse 24. Other engines are not CI-certified — see docs/warehouses.md. Already have dbt/MetricFlow, Cube, LookML, Ossie, or Malloy? grane init --provider ../your_project imports those definitions instead of copying YAML; what Grane cannot compile faithfully is skipped with a reason, never guessed. See docs/warehouses.md and docs/providers.md.

Production HTTP (Docker, TLS, agent tokens, audit log): docs/production.md.

What Grane is not

No dashboards, no chart builder, no built-in chatbot, no hosted data plane, no required LLM API key.

Development

npm install
npm run setup                                            # guided demo or own warehouse + MCP
npm run demo
npm run test:unit                                        # no database needed
docker compose up -d postgres --wait
npm test                                                 # unit + integration

npm run test:benchmark                                   # A/B/C thesis on the demo shop
npm run test:gauntlet                                    # internal robustness gauntlet

tests/gauntlet is the internal robustness suite: a hostile warehouse and hundreds of scenarios designed to make Grane return the wrong number, bypass a permission, or label exploration as governed. See tests/gauntlet/README.md. Adopters put their own query + gold YAML next to grane.yml and run grane test (docs/tests.md).

License

Apache-2.0

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Provides a read-only PostgreSQL SQL surface for LLM agents via MCP, with defense-in-depth security layers for safe database queries.
    3
    MIT
  • F
    license
    Not graded
    quality
    F
    maintenance
    Provides read-only SQL query access to Postgres and DuckDB databases via MCP tools, with extensive security hardening for public endpoints.
    1
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Exposes read-only PostgreSQL queries as typed MCP tools, enabling natural-language data analysis while keeping raw tables hidden and enforcing safety limits.
    MIT