Orionbelt Semantic Layer

by ralfbecher

264 downloads
Not rated
GitHub

About

OrionBelt Semantic Layer is an API-first engine that transforms declarative YAML model definitions into optimized SQL for Postgres, Snowflake, ClickHouse, Dremio, and Databricks. It provides a unified abstraction over your data warehouse, so analysts and applications can query us

Details

Author
ralfbecher
Downloads
264
Categories
Knowledge Base

- 5 SQL dialects: Postgres, Snowflake, ClickHouse, Dremio, Databricks
- AST‑based SQL generation (no string concatenation)
- YAML semantic models with dimensions, measures, metrics, and joins
- Automatic join path resolution with Composite Fact Layer support
- Vendor‑specific SQL validation via sqlglot (non‑blocking)
- Precise error reporting with YAML source positions and join graph analysis
- TTL‑scoped session management via REST API and MCP
- ER diagram generation (Mermaid) via API and Gradio UI
- 9 MCP tools + 3 prompts for AI‑assisted model development
- Gradio UI for interactive model editing and SQL compilation

Setting up with Highlight

This MCP is not yet compatible with Highlight’s one-click setup. However, you can still use it with Highlight by following these steps:

  1. Download and install Highlight from highlightai.com/download
  2. Navigate to the plugins tab and select "Add Custom Plugin"
  3. Configure the plugin with the settings below
    Plugin Name Orionbelt Semantic Layer
    Command (node, npx, python, etc.)

    Please refer to the README for specific instructions on how to obtain API keys or other required environment variables.

  4. Enable "Start Automatically" if you want the plugin to start when Highlight launches

From the repository

Clone the repository, install dependencies with uv sync, then start the REST API with uv run orionbelt-api (available at http://127.0.0.1:8000) or the MCP server with uv run orionbelt-mcp. For Claude Desktop, add the server to claude_desktop_config.json. Optionally install the Gradio UI with uv sync --extra ui and access it at /ui.

get_json_schema

Get a published JSON Schema by name. Returns the raw JSON Schema document as a JSON string so callers can validate documents locally without round-tripping them to the API.

describe_model

Describe the contents of the model. Shows data objects (with columns and joins), dimensions, measures, and metrics. In multi-model mode, use this after loading a model to explore its structure.

get_model_diagram

Generate a Mermaid ER diagram for the model. Returns a Mermaid diagram script that visualises the data objects, columns, and join relationships in the model.

get_join_graph

Return the join graph as an adjacency list. Shows the data object nodes and join edges (with cardinality and join columns) in the model. Useful for understanding table relationships.

find_composables

Resolve which artefacts can still be added to a query (ACR). Artefacts Composability Resolution: given an anchor — your in-progress query, or one or more named artefacts — returns the dimensions, measures, and metrics that remain composable with it and are guaranteed to compile into a valid, fanout-free result. It walks the same join graph the compiler uses, so anything it reports is safe to add. Supply the anchor exactly one of two ways: - ``query_json`` — an in-progress QueryObject as a JSON string (recommended). Its ``select`` dimensions and measures form the anchor. - ``anchors`` — one or more artefact names. Repeated names are intersected. Omit both for a fresh query, where everything composes. Directly composable artefacts share a fanout-safe root with the anchor. CFL measures/metrics come from an independent fact and compose only through the Composite Fact Layer (UNION ALL at the shared grain); they are reported separately.

get_model_graph

Get the OBSL-Core RDF graph for the model as Turtle. Returns the semantic model's RDF graph serialized in Turtle format. The graph follows the OBSL-Core ontology and can be used for semantic web integration or further analysis.

query_model_graph_by_sparql

Execute a read-only SPARQL query against the model's RDF graph. Supports SELECT and ASK queries only (no INSERT/DELETE/UPDATE). The graph uses the OBSL-Core ontology.

find_artefacts

Look up model artefacts (dimensions, measures, metrics). Two modes, selected by whether you pass ``query``: - ``query`` set → fuzzy, ranked search. Matches names and synonyms (exact, synonym, and fuzzy/partial) and returns ranked candidates — for "I don't know the exact name". ``name`` is ignored in this mode. - ``query`` omitted → exact, deterministic, complete enumeration (the authoritative set). No args → every dimension, measure, and metric; ``kind`` only → the complete set of that one kind; ``name`` → that exact artefact (optionally constrained to ``kind``). ``kind`` narrows either mode to one artefact kind.

explain_artefact

Explain the lineage of a dimension, measure, or metric. Traces the composition chain from the named artefact down to the underlying data objects and columns. Useful for understanding how a measure is computed or where a dimension originates.

list_examples

List canonical example queries authored alongside the model. Returns each example's name, description, and intent tags. Use ``get_example`` for full detail (query payload + compiled SQL preview).

get_example

Get a single example by name with its query and compiled SQL preview.

execute_query

Compile and execute a semantic query (QueryObject), returning SQL + results. Pass ``query_json`` — a QueryObject as a JSON string. If no ``limit`` is set, a server-side default row limit applies.

get_model

Get the pre-loaded OBML YAML model source. Returns the original OBML YAML that was loaded into the API at startup. Useful for understanding the model definition in the author's terms. (Single-model mode only.)

Claude Desktop / Cursor

Paste into your MCP client config file to install this server.

{
    "mcpServers": {
        "orionbelt semantic layer": {
            "orionbelt": {
                "command": "npx",
                "args": [
                    "mcp-remote",
                    "https://orionbelt.ralforion.com/mcp",
                    "--transport",
                    "http"
                ]
            }
        }
    }
}

McpServers

{
    "orionbelt": {
        "command": "npx",
        "args": [
            "mcp-remote",
            "https://orionbelt.ralforion.com/mcp",
            "--transport",
            "http"
        ]
    }
}

<!-- mcp-name: io.github.ralfbecher/orionbelt-semantic-layer -->
<p align="center">
OrionBelt Logo
</p>

<h1 align="center">OrionBelt Semantic Layer</h1>

<p align="center"><strong>Compile YAML semantic models into analytical SQL across multiple database dialects</strong></p>

Version 0.4.0
Python 3.12+
License: Apache 2.0
FastAPI
Pydantic v2
Gradio
FastMCP
sqlglot
Docker
Ruff
mypy

PostgreSQL
Snowflake
ClickHouse
Dremio
Databricks

OrionBelt Semantic Layer is an API-first engine that transforms declarative YAML model definitions into optimized SQL for Postgres, Snowflake, ClickHouse, Dremio, and Databricks. It provides a unified abstraction over your data warehouse, so analysts and applications can query using business concepts (dimensions, measures, metrics) instead of raw SQL. Every capability — model loading, validation, query compilation, and diagram generation — is exposed through a REST API and an MCP server, making OrionBelt easy to integrate into any application, workflow, or AI assistant.

Features



- 5 SQL Dialects — Postgres, Snowflake, ClickHouse, Dremio, Databricks SQL with dialect-specific optimizations
- AST-Based SQL Generation — Custom SQL AST ensures correct, injection-safe SQL (no string concatenation)
- OrionBelt ML (OBML) — YAML-based semantic models with data objects, dimensions, measures, metrics, and joins
- Star Schema & CFL Planning — Automatic join path resolution with Composite Fact Layer support for multi-fact queries
- Vendor-Specific SQL Validation — Post-generation syntax validation via sqlglot for each target dialect (non-blocking)
- Validation with Source Positions — Precise error reporting with line/column numbers from YAML source, including join graph analysis (cycle and multipath detection, secondary join constraints)
- Session Management — TTL-scoped sessions with per-client model stores for both REST API and MCP
- ER Diagram Generation — Mermaid ER diagrams via API and Gradio UI with theme support, zoom, and secondary join visualization
- REST API — FastAPI-powered session endpoints for model loading, validation, compilation, diagram generation, and management
- MCP Server — 9 tools + 3 prompts for AI-assisted model development via Claude Desktop and other MCP clients
- Gradio UI — Interactive web interface for model editing, query testing, and SQL compilation with live validation feedback
- Plugin Architecture — Extensible dialect system with capability flags and registry

Quick Start



Prerequisites



- Python 3.12+
- uv package manager

Installation



``bash
git clone https://github.com/ralfbecher/orionbelt-semantic-layer.git
cd orionbelt-semantic-layer
uv sync
`

Run Tests



`bash
uv run pytest
`

Start the REST API Server



`bash
uv sync --extra ui # include Gradio UI (optional)
uv run orionbelt-api

or with reload:


uv run uvicorn orionbelt.api.app:create_app --factory --reload
`

The API is available at
http://127.0.0.1:8000. Interactive docs at /docs (Swagger UI) and /redoc. When the ui extra is installed, the Gradio UI is available at /ui.

Start the MCP Server



`bash

stdio (default, for Claude Desktop / Cursor)


uv run orionbelt-mcp

HTTP transport (for multi-client use)


MCP_TRANSPORT=http uv run orionbelt-mcp
`

Example



Define a Semantic Model



`yaml

yaml-language-server: $schema=schema/obml-schema.json


version: 1.0

dataObjects:
Customers:
code: CUSTOMERS
database: WAREHOUSE
schema: PUBLIC
columns:
Customer ID:
code: CUSTOMER_ID
abstractType: string
Country:
code: COUNTRY
abstractType: string

Orders:
code: ORDERS
database: WAREHOUSE
schema: PUBLIC
columns:
Order ID:
code: ORDER_ID
abstractType: string
Order Customer ID:
code: CUSTOMER_ID
abstractType: string
Price:
code: PRICE
abstractType: float
Quantity:
code: QUANTITY
abstractType: int
joins:
- joinType: many-to-one
joinTo: Customers
columnsFrom:
- Order Customer ID
columnsTo:
- Customer ID

dimensions:
Country:
dataObject: Customers
column: Country
resultType: string

measures:
Revenue:
resultType: float
aggregation: sum
expression: "{[Orders].[Price]} {[Orders].[Quantity]}"
`

The
yaml-language-server comment enables schema validation in editors that support it (VS Code with YAML extension, IntelliJ, etc.). The JSON Schema is at schema/obml-schema.json.

Define a Query



Queries select dimensions and measures by their business names:

`yaml
select:
dimensions:
- Country
measures:
- Revenue
limit: 100
`

Compile to SQL (Python)



`python
from orionbelt.compiler.pipeline import CompilationPipeline
from orionbelt.models.query import QueryObject, QuerySelect
from orionbelt.parser.loader import TrackedLoader
from orionbelt.parser.resolver import ReferenceResolver

Load and parse the model


loader = TrackedLoader()
raw, source_map = loader.load("model.yaml")
model, result = ReferenceResolver().resolve(raw, source_map)

Define a query


query = QueryObject(
select=QuerySelect(
dimensions=["Country"],
measures=["Revenue"],
),
limit=100,
)

Compile to SQL


pipeline = CompilationPipeline()
result = pipeline.compile(query, model, "postgres")
print(result.sql)
`

Generated SQL (Postgres):

`sql
SELECT
"Customers"."COUNTRY" AS "Country",
SUM("Orders"."PRICE"
"Orders"."QUANTITY") AS "Revenue"
FROM WAREHOUSE.PUBLIC.ORDERS AS "Orders"
LEFT JOIN WAREHOUSE.PUBLIC.CUSTOMERS AS "Customers"
ON "Orders"."CUSTOMER_ID" = "Customers"."CUSTOMER_ID"
GROUP BY "Customers"."COUNTRY"
LIMIT 100
`

Change the dialect to
"snowflake", "clickhouse", "dremio", or "databricks"` to get dialect-speci

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.