by OpenLabs-so
Provides privacy‑first, cookieless web analytics with revenue attribution and an MCP server, enabling self‑hosted tracking without cookies or cross‑site identifiers.
OpenAnalytics delivers a fully self‑hosted web analytics stack that respects user privacy. It captures page views, custom events, sessions, web vitals, funnels, and revenue data from your Stripe account without using cookies, fingerprinting, or cross‑site profiles. All data stays on your infrastructure, stored in PostgreSQL (control plane) and ClickHouse (event store).
SELF-HOSTING.md).docker compose pull && docker compose up -d after generating secrets with ./generate-secrets.sh --domain yourdomain.com --email you@yourdomain.com --with-geoip.https://app.yourdomain.com to create the first account.<script src="https://c.yourdomain.com/tracker.js"></script>) to any site you want to monitor.apps/api for AI‑assisted querying.oa command for site setup, stats retrieval, and device‑flow login.Q: Do I need a build toolchain to run OpenAnalytics? A: No. The recommended installation pulls pre‑built Docker images; only Docker and a Linux host are required.
Q: Can I run OpenAnalytics on ARM hardware?
A: Images are built for amd64. On ARM you must rebuild the ten images locally (pnpm run build).
Q: How is visitor identity handled? A: A daily‑rotating salted hash is generated per visitor; it never persists beyond the day and is never linked to personal data.
Q: Is geolocation data sent to third parties? A: No. The geolocation database is downloaded once and queried locally; no external lookups occur.
Q: What happens during an upgrade?
A: ./upgrade.sh applies migrations; rollbacks require a full restore because migrations are irreversible.
Q: How do I integrate the MCP server?
A: The MCP endpoint is exposed via the API service. Use the signed query envelopes (Ed25519) as documented in packages/contracts.
Q: Are there any licensing restrictions? A: The code is AGPL‑3.0. Running a modified service as a network service obliges you to provide the source to users.
Open-source, privacy-first web analytics. One lightweight tracker script, no cookies, no cross-site profiles, aggregate-only reads — self-hostable on your own hardware under AGPL-3.0.
A hosted instance runs at getopen.so, operated by the authors: the same code, someone else's servers.

▶ Watch the dashboard in motion, a tour of these same screens on YouTube.
The product, as one pnpm monorepo:
| App | Role |
|---|---|
apps/tracker |
The browser snippet — a few KiB, with a byte budget CI enforces |
apps/collector |
Ingest: validates, sanitizes, rate-limits, enqueues |
apps/worker |
Drains the queue into ClickHouse; sessions, rollups, exports, mail, deletions |
apps/api |
Control plane: auth, sites, keys, sharing, event definitions, funnels, widgets, revenue, AI assistant, MCP |
apps/query-gateway |
The only process allowed to read ClickHouse; verifies signed query envelopes |
apps/realtime |
The SSE stream behind the live dashboard |
apps/web |
The dashboard (Next.js) |
apps/cli |
oa — site setup, stats, device-flow login |
packages/* |
domain, postgres (+migrations), clickhouse (+migrations), redis, auth, contracts (OpenAPI), observability, integrations, migrations, testkit |
Stores: Postgres (control plane), ClickHouse (events and rollups), Valkey ×2 (one durable event queue, one losable realtime cache).
What it does, in one list: page views, custom and attribute-driven events, sessions, web vitals, funnels, per-site retention, embeddable widgets, public share links, revenue analytics from your Stripe account, CSV/JSON import and export, an MCP server, and a CLI.
Who is on the site now, from a presence cache rather than a table scan. Names are generated per visitor and mean nothing outside the day they were minted.

Where one visitor went, session by session. The identity behind a trail is a salted hash that rotates every night, so the trail is as long as a visit and never as long as a person.

Where they are, at city level and only when a site opts in. The lookup runs against a database on your own disk and never leaves the host.

Architecture rules CI enforces, not conventions:
apps/web may import only packages/contracts — the OpenAPI document is the
single seam between frontend and backend.SELF-HOSTING.md is the guide: a generator script, one
docker compose up -d, automatic TLS, and an explanation of every secret and
every failure mode. Requirements are a Linux host with Docker, four DNS records,
about 4 GB of RAM and 25 GB of free disk.
Installing is a pull, not a build. A release publishes ten images to
ghcr.io/openlabs-so/openanalytics, so a fresh host is a few minutes and needs
no toolchain on it.
Point four names at the host before you start. Certificates are issued on the first boot and issuance fails without them, half an hour later and nowhere near the cause:
app.example.com api.example.com c.example.com rt.example.com
git clone https://github.com/OpenLabs-so/openanalytics
cd openanalytics
git checkout "$(git tag -l 'v*' --sort=-v:refname | sed '/-/d' | head -1)" # newest release, not main
cd infra/selfhost
./generate-secrets.sh --domain example.com --email you@example.com --with-geoip
docker compose pull && docker compose up -d
# then open https://app.example.com and create the first account
The checkout is where the version is chosen, and it is chosen once. The
generator reads the tag back out of the tree it is standing in and points .env
at that release's images, printing which it picked and why; on a branch, on
main, or with no git at all it writes the build defaults instead. That is not
a convenience — the compose file, the env templates and the migrations ship
with the images, so a release's images against another tree is a configuration
nobody has tested.
Images are amd64. On arm64, or to run a branch, build the ten here instead:
same compose file, one flag, about ten minutes and swap on a 4 GB box. Later,
./upgrade.sh moves between releases and takes the snapshot ./rollback.sh
needs, because migrations do not go down: the way back is a restore, and a
restore discards what arrived after the upgrade. It tells you that before it
starts, not at rollback time when you no longer have a choice.
RELEASING.md is what a version number here means.
To run it from source instead — for development, or to slot the services into
infrastructure you already have — follow
Running from source. The order matters
and one obvious order does not work: the migration runners are compiled
output, so pnpm run build comes before pnpm run migrate:postgres.
infra/selfhost/env/*.env.example documents every variable each service reads,
and there is one file per service on purpose — the environment schema forbids
some keys to some services, so a single shared .env cannot be correct. The
AI assistant (OPENAI_API_KEY) and object storage are optional: unset, those
surfaces disable themselves and everything else runs.
Run the test suite the way CI does:
pnpm run test # unit + contract + tracker, no infrastructure needed
pnpm run verify # everything CI checks, including boundaries and the size budget
No cookies, no fingerprinting, no cross-site identifiers. Visitor identity is a daily-rotating salted hash; raw IP addresses are never stored. Do Not Track and Global Privacy Control are honored at the collector, before anything is written. City-level geolocation is opt-in per site.
Geolocation is resolved locally against a database on your own disk — no lookup
ever leaves the host. None is bundled (a 60 MB download, and stale within a month);
infra/selfhost/geoip/fetch-dbip.sh downloads one.
IP Geolocation by DB-IP — https://db-ip.com — used under CC BY 4.0.
Pull requests are merged here, with your name on the commit. This repository used to receive periodic exports from a private monorepo, and a merged PR was flattened by the next one; that ended in August 2026. A bot asks you to sign the CLA once — it is not an assignment, you keep your copyright — and there is no DCO sign-off on top of it.
CONTRIBUTING.md has the setup, the ground rules CI enforces, and where to start. Discussions are for questions and for ideas worth talking through first.
Security reports: SECURITY.md — please not a public issue.
Code: AGPL-3.0. If you run a modified OpenAnalytics as a network service, the AGPL requires you to offer your modified source to its users.
The "OpenAnalytics" name and the hosted service's domain identify the instance its authors operate and are not part of the license grant. A self-hosted instance runs the software, not the brand.
Please log in to share your review and rating for this MCP.
Explore related MCPs that share similar capabilities and solve comparable challenges
by mindsdb
Enables humans, AI agents, and applications to retrieve highly accurate answers across large‑scale data sources, unifying heterogeneous databases, warehouses, and SaaS platforms.
by mckinsey
Build high-quality data visualization apps quickly using a low-code toolkit that leverages Plotly, Dash, and Pydantic.
by antvis
Offers over 25 AntV chart types for automated chart generation and data analysis, callable via MCP tools, CLI, HTTP, SSE, or streamable transports.
by dbt-labs
Provides a Model Context Protocol server that exposes a rich set of dbt‑related tools—SQL execution, semantic‑layer queries, discovery APIs, dbt CLI commands, admin operations, code generation, lineage analysis, and product documentation retrieval—so AI agents can safely interact with dbt projects and platforms.
by reading-plus-ai
A versatile tool that enables interactive data exploration through prompts, CSV loading, and script execution.
by Canner
Provides a semantic engine that lets MCP clients and AI agents query enterprise data with contextual understanding, precise calculations, and built‑in governance.
by surendranb
Provides natural‑language access to Google Analytics 4 data via MCP, exposing over 200 dimensions and metrics for Claude, Cursor and other compatible clients.
by ergut
Provides secure, read‑only access to BigQuery datasets, allowing large language models to query and analyze data through a standardized interface.
by isaacwasserman
Provides an interface for LLMs to visualize data using Vega‑Lite syntax, supporting saving of data tables and rendering visualizations as either a full Vega‑Lite specification (text) or a base64‑encoded PNG image.