Saiku Analytics

Open-source Semantic Layer analytics for cubes — drag-and-drop in the browser, SQL through Mondrian + Calcite, and a typed REST surface so AI agents can query without ever seeing MDX.

saiku.bi · Live demo · Issues · Discussions

Latest release License: Apache 2.0 + EPL 1.0 Docker image Slack community

*** ## Try it in 30 seconds ```sh docker run -d -p 8080:8080 --name saiku -e SAIKU_DEMO=true ghcr.io/spiculedata/saiku ``` Then open and log in with `admin` / `admin`. Demo mode ships a self-contained H2 + FoodMart cube — drag fields onto rows, columns, or filters and the SPA writes MDX for you. > **For a real deployment**, drop `SAIKU_DEMO=true` and set an admin password: > `-e SAIKU_ADMIN_PASSWORD='a-strong-password'`. Saiku **refuses to start** on the > default `admin`/`admin` once it's network-reachable, so one of those two is > required. A hosted instance is always live at (auto-reset nightly). ## What is Saiku Saiku started in 2010 as an open-source OLAP browser for Mondrian. In 2026 it was rebuilt as a modern Semantic Layer on top of: - **Mondrian 4.8.1.x (Spicule fork)** — with a Calcite-based SQL planner alongside the legacy `SqlQuery` builder. Calcite is the default; force legacy with `-Dmondrian.backend=legacy`. - **Apache Arrow** wire format for cellsets, so the browser and any programmatic consumer share a zero-copy result envelope. - **Jetty 12 EE10 + Jersey 3.1 + Spring 6 + Spring Security 6.5** in a single-JAR Picocli launcher. - **SvelteKit 5 + Vite** for the SPA (separate repo, served from inside the same JAR at `/ui/`). ## AI Query API + MCP Saiku 4.x exposes a typed REST surface — `/rest/saiku/api/ai/*` — designed for LLM agents. Hierarchies, levels, measures and synonyms are discoverable via `/ai/cubes` and `/ai/schema`, and a single `POST /ai/query` translates a JSON description of a question into validated MDX, runs it, and returns typed `{value, formatted, unit}` cells. Every validation failure carries a `{status, field, available}` envelope so an agent can self-correct without scraping logs. The container also bundles **`saiku-mcp`**, a stdio [Model Context Protocol](https://modelcontextprotocol.io) wrapper so Claude Desktop / Cursor / Cline can wire to a running Saiku with one line of config: ```json { "command": "docker", "args": ["exec", "-i", "saiku", "saiku-mcp"] } ``` See [`docs/AI-QUERY-API.md`](docs/AI-QUERY-API.md) and [`docs/schema-annotations.md`](docs/schema-annotations.md) for the typed contract and the `saiku.semantic.*` annotation namespace cubes use to describe themselves to agents. ## Dashboards Build shareable dashboards of chart / table / KPI / text / image tiles over your cubes — with cross-tile filters, click- and brush-cross-filtering, drill-down/through, conditional formatting, combo charts, anomaly/forecast overlays, auto-refresh, PDF/PNG export and read-only share links. See the [`docs/dashboards-user-guide.md`](docs/dashboards-user-guide.md) for the full walkthrough, and [`saiku-ui/src/embed/README.md`](saiku-ui/src/embed/README.md) to embed a dashboard in your own app via the `` web component. ## Observability Saiku ships **opt-in OpenTelemetry instrumentation** via the OTel Java agent — zero code changes, zero overhead when off. Setting `OTEL_EXPORTER_OTLP_ENDPOINT` activates auto-instrumentation for Jetty, Jersey, JDBC (every Mondrian-emitted SQL becomes a child span), outbound HTTP, JVM metrics, and DBCP2 connection pool metrics. Trace context is injected into the Saiku log pattern automatically. ```sh docker run -d -p 8080:8080 \ -e OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318 \ -e OTEL_SERVICE_NAME=saiku-prod \ ghcr.io/spiculedata/saiku:latest ``` Without the endpoint env var the agent is never loaded. See [`docs/observability.md`](docs/observability.md) for the full env-var reference, sampling guidance, and what's not yet covered (Tier 2 custom spans for `ThinQueryService` etc.). ## Build from source JDK 21 + Maven 3.9+ required. **Set up GitHub Packages auth first, or the build fails before it compiles.** Saiku's Mondrian fork, olap4j, saiku-query and Ossie artifacts are published to GitHub Packages, which requires an authenticated token **even though the packages are public**. Without it you get a bare `401 Unauthorized` on `pentaho:mondrian` that never mentions tokens: 1. Create a **classic** personal access token with only the `read:packages` scope ([Tokens (classic)](https://github.com/settings/tokens/new)). It must be classic — [GitHub's Maven registry does not accept fine-grained tokens](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-apache-maven-registry), and the UI defaults to fine-grained. Our packages are public, so no `repo` scope or org membership is needed. 2. Add five `` entries to `~/.m2/settings.xml` — `github-mondrian-saiku`, `github-olap4j`, `github-olap4j-xmlaserver`, `github-saiku-query`, `github-ossie`. Copy the block from [`.github/workflows/ci.yml`](.github/workflows/ci.yml); one token covers all five. Still getting a 401? A fine-grained token and a classic token missing `read:packages` produce an identical error, so check what the token actually has before minting another — `curl -sI -H "Authorization: token $PAT" https://api.github.com/user | grep -i x-oauth-scopes`. A classic token's scopes are editable in place, and the value doesn't change, so `settings.xml` needs no edit. ```sh # Compile, unit tests, Spotless format check (CI gate): mvn verify # Build the runnable fat-JAR: mvn -pl saiku-launcher -am -Dmaven.test.skip=true package # Run: java -jar saiku-launcher/target/saiku-*.jar serve --port 8080 --home ./saiku-home ``` Whole-API integration tests (boots Jetty + the launcher's WAR in-process against the seeded FoodMart H2 datasource): ```sh mvn verify -P integration ``` See [`CLAUDE.md`](CLAUDE.md) for the full layout, the dependency catalog (`saiku-bom`), and the GitHub Packages auth gotcha for local builds. ## Repository layout ``` saiku-bom/ # central dependency-version catalogue saiku-core/ saiku-olap-util/ # olap4j helpers saiku-service/ # Semantic Layer service, AI Query, schema gen, async, cache saiku-semantic/ # YAML semantic layer saiku-web/ # JAX-RS REST resources saiku-webapp/ # Servlet webapp (Spring XML wiring) saiku-launcher/ # Picocli CLI + embedded Jetty serving the WAR saiku-mcp/ # stdio JSON-RPC MCP wrapper saiku-ui/ # SvelteKit SPA (independent versioning) ``` The SvelteKit SPA lives in `saiku-ui/` and is built independently; the launcher serves the static `dist/` under `/ui/`. ## Getting help - **Bugs and feature requests**: [open an issue](https://github.com/spiculedata/saiku/issues/new/choose). - **Questions, ideas, walkthroughs**: [GitHub Discussions](https://github.com/spiculedata/saiku/discussions). - **Chat**: [Saiku Cloud Slack](https://join.slack.com/t/saikucloud/shared_invite/zt-3yor7kgiv-YUPhqK0pvd4WljctIQVOTA). - **Stack Overflow tag**: [`saiku`](https://stackoverflow.com/questions/tagged/saiku). - **Commercial support, hosted, training**: . The old `groups.google.com/a/saiku.meteorite.bi` lists and `##saiku` IRC channel are no longer monitored. ## Contributing See [CONTRIBUTING.md](./CONTRIBUTING.md). Short version: - `feature/` branch off `development` — see the Gitflow note in [CLAUDE.md](CLAUDE.md). - Run `mvn spotless:apply` before committing (a pre-commit hook is available via `./scripts/install-hooks.sh`). - Tests live in `**/src/test/java/`; integration tests in `saiku-launcher/src/test/java/org/saiku/launcher/it/`. - Open the PR against `development`, not `main`. `main` is the release branch — only release/* and hotfix/* PRs go there. ## License Saiku is dual-licensed under **Apache 2.0** and **EPL 1.0**. See [`LICENSE`](LICENSE). A summary lives at . ## History The original Saiku project was started by Tom Barber and Paul Stoellberger in 2010 at Meteorite BI and now lives at [Spicule](https://spicule.co.uk). Contributors are listed on the [GitHub contributors page](https://github.com/spiculedata/saiku/graphs/contributors). For release notes see [Releases](https://github.com/spiculedata/saiku/releases). **[⬆ back to top](#readme)**