A strictly read-only, natural-language data analyst. Point it at a Postgres database and read-only APIs, then ask questions in plain English. It runs on your locally authenticated Claude Code CLI, so there is no API key to manage.
Documentation: https://velofy.co/querion/
Querion answers like a senior data analyst: the number, the insight, the exact query behind it, and a chart when one helps. It is built to only read.
"new vs returning customers this month, with a chart"
-> Querion plans read-only steps
-> runs SELECTs on Postgres and GETs on your APIs
-> replies with the number, a table, a chart, and the SQL it used
Requirements: Python 3.9+, a Postgres database, and the Claude Code CLI installed and logged in on the host (run claude once).
git clone https://github.com/anishfyi/querion.git
cd querion
pip install -e ".[all]" # core + web UI + charts + .env loadingcp querion.example.yaml querion.yaml
cp .env.example .env # set QUERION_DATABASE_DSN to a READ-ONLY role
querion check # validates config, database, and the claude CLI
querion ask "how many orders were placed in the last 7 days?"
querion serve # web UI at http://127.0.0.1:8000A minimal querion.yaml:
company: "Acme Inc"
model: opus
database:
dsn: ${QUERION_DATABASE_DSN} # a READ-ONLY Postgres role
sources: [] # add platforms here later
limits:
daily_per_user: 50- Read-only checks. SQL must be a single SELECT or WITH statement, HTTP is GET only with an optional per-source allowlist, and explicit write statements in a question are refused. Details and limits are in the safety model.
- Multi-source. Joins history in Postgres with live data from your APIs in one answer.
- Transparent. Every answer shows the SQL that produced it.
- No API key. Uses the Claude Code CLI you already have. Opus is recommended.
- Web UI and JSON API.
querion servestarts a FastAPI app. It has no built-in login, so put it behind your own authentication. - Optional semantic layer. Reads a layer maintained by Trove when
trove.enabledis true.
Adding a platform is configuration, not code. Put the secret in .env, describe the read endpoints in a markdown file (see docs/sources/example.md), and add a block:
sources:
- name: stripe
base_url: https://api.stripe.com
auth_header: "Authorization: Bearer ${STRIPE_KEY}"
safe_get: # only these read paths are allowed
- ^/v1/charges
- ^/v1/customers
docs: docs/sources/stripe.mdA GET is not always read-only, so set safe_get for any API that is not strictly RESTful. See Connecting data sources.
The strongest guarantee is a read-only Postgres role and read-only API tokens. Querion adds application checks on top: SQL validation, a read-only database session with a statement timeout, GET-only HTTP, and a write-request firewall. The firewall deterministically catches pasted SQL write statements and GraphQL mutations. Plain-English write requests rely on the model following its instructions, with the other layers as the backstop. Read the safety model for exactly what is enforced.
- Overview
- Installation
- Quickstart
- Configuration reference
- Connecting data sources
- Safety model
- Architecture
- Usage examples
- CLI and web API
- Project status
Issues and pull requests are welcome on GitHub. Open an issue first for larger changes.