The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the Orionbelt Semantic Layer listing page.
Define your metrics once in YAML. Let agents and BI tools query them without ever touching your schema.
A semantic sidecar: it rides alongside the systems you already run instead of replacing them.
Ask an LLM to write SQL against a raw star schema and sooner or later it joins two fact tables and hands you a revenue number inflated by a factor of eight. It looks right. Nobody catches it.
OrionBelt is a semantic sidecar. You declare dimensions, measures, metrics, and joins in version-controlled YAML. OrionBelt compiles them into dialect-specific SQL through a real AST, and routes multi-fact queries through a Composite Fact Layer planner that blocks the join paths that produce fan traps. Agents and BI tools ask for "Total Revenue" by "Country". They never see a table name.
No BI tool in the middle. No runtime lock-in. Point it at what you already have.
Here is TPC-DS query 98. Two measures over the same column, identical but for one line: Class Revenue is pinned to a coarser grain than the query asks for.
That one grain line is what becomes SUM(...) OVER (PARTITION BY "Class") below.
The query names business concepts. No tables, no joins, no SQL:
You did not write the join path, the window function over an aggregate, the NULLIF guard, or one table name. Change -d duckdb to -d snowflake and the same two files compile for Snowflake, or for any of eight dialects.
This is checked, not asserted. 40 TPC-DS queries are built against a single OBML model and compared row by row against each engine's own reference SQL: 39 of 40 match on DuckDB at sf=1, 37 of 40 on ClickHouse at sf=10. Every one of the remaining differences traces to a reference variant rather than a compilation error, and each is documented. See the sweep, or the queries in examples/tpcds_queries/.
The same model serves every surface you already use:
:5432. Tableau, Power BI, Superset, DBeaver, and psql connect with the Postgres driver they already ship. Dremio federates it as a Postgres source.LOAD adbc_scanner, connect, and adbc_scan a governed query into a DuckDB relation you can join, filter, and materialise locally. See Connecting via ADBC.Compiles to BigQuery, ClickHouse, Databricks, Dremio, DuckDB/MotherDuck, MySQL, PostgreSQL, and Snowflake.
OrionBelt is a sidecar, not a platform. It compiles a YAML model into correct SQL and exposes it over the protocols you already use. It does not run a cluster, own your cache, or ask you to adopt a cloud.
Reach for OrionBelt when:
Reach for something else when:
Try the live demo with a pre-loaded model, or open the Colab notebook and run it against TPC-H data.
Try it in 30 seconds · Claude Desktop / MCP · Why OrionBelt? · Features · Example · Documentation · Roadmap · Commercial · Development
Open the Live Demo — Gradio UI with a pre-loaded example model. Paste a query, pick a dialect, see SQL instantly.
API explorer: Swagger UI | ReDoc
Want to try the PostgreSQL wire surface? Cloud Run is HTTPS-only, so the public demo can't expose ports 5432 (pgwire) or 8815 (Flight SQL). Spin the same demo up locally in two commands — it includes the baked-in
orionbelt_1_commerceDuckDB dataset and the full OBSQL surface:The container ships with
PGWIRE_AUTH_MODE=trust(default), so it's safe forlocalhostbut not safe to expose to the public internet. For exposed deployments, setAUTH_MODE=api_key(shipped in v2.12.0): pgwire then negotiates SCRAM-SHA-256 (or cleartext over TLS) against the shared key store.
— Interactive notebook with TPC-H data: explore the model, compile queries across dialects, execute against DuckDB, and see results. Requires Python 3.12 runtime.
Then paste into a Python REPL:
Output:
No env file needed — the compilation pipeline is stateless.
Start the servers:
Use the obsl CLI (no server needed - compiles in-process):
See the CLI guide for all commands.
Smoke-test the Flight SQL surface without a BI tool:
OBSQL — OrionBelt Semantic QL — is the SQL surface BI tools and humans actually write. Bare labels, MEASURE() markers, or matching aggregate wrappers; aggregation-match validation; WITH ROLLUP / WITH CUBE; no escape hatch to raw warehouse SQL. Same language over Arrow Flight SQL (v2.4+) and PostgreSQL wire (v2.5+):
See the OBSQL reference for the full grammar.
Stage 1 — Zero-config start (models loaded later via API or UI):
Open http://localhost:8080/docs to explore the API.
Stage 2 — Realistic setup with docker compose:
See .env.template for the full environment variable reference.
Docker notes:
API_SERVER_HOSTis already0.0.0.0inside the container — no override needed.- MCP via stdio does not work in Docker. Use the MCP HTTP client for containerized deployments.
- Mount models to
/app/models(or any path) and setMODEL_FILES(comma-separated paths) to pre-load on startup.- For production, pin a version tag (
:2.27.2) rather than:latest.
The MCP server is a separate thin client that delegates to the REST API:
Add to your Claude Desktop claude_desktop_config.json:
Also works with Copilot, Cursor, and Windsurf. See the MCP repo for full setup options.
| OrionBelt | dbt Semantic Layer | Cube | Malloy | |
|---|---|---|---|---|
| Model format | YAML-only (OBML) | Python + YAML | JavaScript | Custom DSL |
| SQL generation | AST-based (injection-safe) | String templates | String templates | Compiler |
| Multi-dialect | 8 dialects, no runtime lock-in | dbt Cloud required | Cube Cloud or self-host | BigQuery-focused |
| Multi-fact queries | Star Schema + CFL planner (fan-trap prevention) | Limited | Pre-aggregations | Automatic joins |
| Integration surface | REST API + MCP + Gradio UI | dbt Cloud API | REST + GraphQL | VS Code extension |
| Deployment | Self-host anywhere, single binary | SaaS (Cloud) | SaaS or self-host | Library |
| License | BUSL-1.1 (converts to Apache 2.0) | Apache 2.0 | AGPL / proprietary | MIT |
#,##0.00, 0.00%) on measures/metrics with locale-aware renderingdefaultTimezone fallback and ISO 8601 serializationexamples/obsql.py, a tiny terminal CLI for testing the Flight surface without a BI tooladbc_scanner community extension, a plain DuckDB shell queries the layer over Flight SQL: adbc_scan returns a relation, so governed measures join to local tables and land in CREATE TABLE AS. Arrow the whole way, no conversion at either end:5432. Every BI tool already ships a Postgres ODBC/JDBC driver, so the user side is "point your existing connection at OBSL and go" — Tableau, DBeaver, Superset, Power BI, plain psql, and Dremio as a federated Postgres source (Dremio → OBSL → optionally back to Dremio's lakehouse, full circle)health block with orphan dataObjects, fan-trap risks, and unreachable dimensions — agents skip the defensive second round tripPOST /query/plan returns the planner's understanding (planner choice, physical tables, join path, would_compile) without compiling SQL or executing; opt-in include_database_explain adds the warehouse's raw EXPLAINwarnings list across the API uses a stable {code, severity, message, path, hint, context} shape with a documented code taxonomy; agents branch on codes instead of parsing messages/find Recovery — when a search produces no exact or synonym hits, deterministic Levenshtein + trigram fallback returns near-miss candidates with scores and reasonsexamples: block of canonical queries; GET /examples (with ?intent= filtering) gives agents one-round-trip discovery of what a model is designed to answerrefresh: blocks on dataObject entries (interval / heartbeat / static); the cache derives query TTLs from the contracts of the physical tables a query touched, not from caller guessesPOST /v1/heartbeat to a physical table invalidates every cached query that depends on it, across every dataObject and sessionCACHE_BACKEND=fileyaml-language-server)Change dialect to bigquery, clickhouse, databricks, dremio, duckdb, mysql, or snowflake for dialect-specific SQL.
QUERY_EXECUTE=true)
Embedded mode — the UI is mounted at /ui on the API server:
Standalone mode — run API and UI as separate processes:
| Topic | Link |
|---|---|
| Full docs site | ralforion.com/orionbelt-semantic-layer |
| Installation | getting-started/installation |
| Quick Start | getting-started/quickstart |
| Docker & Deployment | getting-started/docker |
| Development | getting-started/development |
| OBML Model Format | guide/model-format |
| Query Language | guide/query-language |
| SQL Dialects | guide/dialects |
| Period-over-Period Metrics | guide/period-over-period |
| Trend Analysis (rank / lag / lead / ntile, partitioned MAs, statistical aggregates) | guide/trend-analysis |
| Compilation Pipeline | guide/compilation |
| OBSL Graph & SPARQL | guide/obsl |
| Gradio UI | guide/ui |
| AI Integrations | guide/integrations |
| OSI Interoperability | guide/osi |
| REST API Endpoints | api/endpoints |
| DB-API Drivers & Flight SQL | drivers |
| Architecture | reference/architecture |
| Configuration | reference/configuration |
| Sales Model Walkthrough | examples/sales-model |
| Multi-Dialect Output | examples/multi-dialect |
| Multi-Fact: Sales & Returns | examples/multi-fact |
| TPC-DS Benchmark | examples/tpcds |
| Quickstart Notebook | examples/quickstart.ipynb |
| Comparison: Overview | comparison/ |
| Comparison: vs. dbt Semantic Layer | comparison/dbt |
| Comparison: vs. Malloy | comparison/malloy |
| Comparison: vs. LookML / Looker | comparison/lookml |
| Comparison: vs. Cube | comparison/cube |
| Comparison: vs. AtScale | comparison/atscale |
| Status | Area |
|---|---|
| Shipped | 8 SQL dialects, REST API, MCP server, Gradio UI, DB-API drivers, Flight SQL, PostgreSQL wire protocol (v2.5.0+) — Tableau / DBeaver / Superset / Power BI / psql / Dremio as a federated Postgres source, OBSL/SPARQL, OSI v0.2 interop with bidirectional schema validation, AI integrations (LangChain, CrewAI, ADK, etc.), model inheritance & extends, data types & numerical precision, timezone settings, grain & filter context overrides, Trend Analysis — partitioned rolling windows, MetricType.WINDOW for rank/lag/lead/ntile, 9 statistical aggregates (CORR, COVAR_, REGR_, STDDEV_, VAR_), Unified authentication (v2.12.0) across REST / Flight / pgwire / UI — AUTH_MODE=api_key with shared key store, pgwire SCRAM-SHA-256 + cleartext, Artefacts Composability Resolution (ACR, v2.14.0): a composables endpoint that, given the query so far, returns which dimensions / measures / metrics can still be added (including CFL candidates), powering guided query building |
| Planned | OIDC / SSO authentication & per-token authorization scopes, CLI for automation & CI/CD, DDL view generation (CREATE VIEW from queries), additional dialects, additional BI tool integrations, pre-aggregation / materialization layer |
OrionBelt Semantic Layer is source-available under BUSL-1.1 until its Apache-2.0 conversion — the free distribution has full parity on the shipped v2.6 surface and is production-grade for self-hosted use. For teams that want production support, a managed runtime, or embedded analytics terms, RALFORION offers:
Contact RALFORION d.o.o. for details.
An ontology-based MCP server that analyzes relational database schemas and generates RDF/OWL ontologies. Together with OrionBelt Semantic Layer, it enables AI assistants to navigate your data landscape through ontologies and compile safe, dialect-aware analytical SQL.
Contributing to OrionBelt or running from source:
Every uses: in .github/workflows is pinned to a 40-character commit SHA
rather than a tag, because a tag such as v7 is a movable label: it runs
whichever commit its owner has pointed it at when the job starts. The
# vX.Y.Z comment beside each SHA names the exact patch release that SHA was
cut from, and it has to be a patch release, since a major tag moves with every
upstream bump.
Pinning fixes which code runs but makes the reference unreadable, so
scripts/check-action-pins.sh keeps the SHA and its comment honest. It walks
every uses: line and requires a commit SHA, an owner from its ALLOWED_OWNERS
allowlist, and an exact-patch version comment, then resolves that tag upstream
with git ls-remote and fails when the commit it names is not the one pinned.
Container actions must be pinned by digest; local ./ actions are skipped.
--offline checks only the SHA and comment format, with no network calls.
The check runs as the pins job in CI, and as the first step after checkout in
the workflows that publish (Docker, PyPI, docs), so a tag can never ship
artifacts built by steps whose pins were never verified. Adding an owner to
ALLOWED_OWNERS is a deliberate decision: a SHA matching its own tag says
nothing about whether that action belongs in this repo at all.
Copyright © 2026 RALFORION d.o.o.
OrionBelt® is a registered trademark of RALFORION d.o.o.
Licensed under the Business Source License 1.1 (SPDX: BUSL-1.1). The Licensed Work will convert to Apache License 2.0 on 2030-03-16.
Third-party works redistributed by OrionBelt, and their terms, are listed in THIRD_PARTY_NOTICES.md.
By contributing to this project, you agree to the Contributor License Agreement.
For commercial licensing inquiries, contact: licensing@ralforion.com