> hypequery

Introduction

Build a type-safe ClickHouse analytics backend with a TypeScript query builder, semantic datasets, multi-tenant APIs, React hooks, and MCP tools.

A TypeScript semantic layer for ClickHouse

hypequery gives TypeScript teams one place to define ClickHouse analytics and reuse them in backend code, HTTP APIs, React dashboards, and MCP tools for AI agents. It is an open-source library that runs inside your application—not a hosted BI platform or a separate semantic-layer server.

Start with the type-safe query builder when a query is local. Add a dataset when dimensions, measures, metrics, tenant isolation, and time grains become shared product meaning. Add Serve, React, or MCP only when another consumer needs the same contract.

The canonical dataset

import { dataset, dimension, measure } from '@hypequery/datasets';

export const Orders = dataset('orders', {
  source: 'orders',
  tenantKey: 'tenant_id',
  timeKey: 'created_at',
  dimensions: {
    id: dimension.string(),
    region: dimension.string(),
    status: dimension.string(),
    createdAt: dimension.timestamp({ column: 'created_at' }),
  },
  measures: {
    revenue: measure.sum('amount'),
    orderCount: measure.count('id'),
    p95OrderValue: measure.percentile('amount', 0.95),
    latestStatus: measure.argMax('status', 'createdAt'),
  },
});

export const revenue = Orders.metric('revenue', {
  measure: 'revenue',
  label: 'Revenue',
});

This is ordinary TypeScript: review it in a pull request, test it in CI, import it in a worker, serve it as an API, consume it with a typed React hook, or expose it as a bounded MCP tool.

The packages

PackageRole
@hypequery/clickhouseSchema generation and a type-safe ClickHouse query builder
@hypequery/datasetsCode-first semantic datasets, dimensions, measures, metrics, relationships, time grains, and tenant rules
@hypequery/serveValidated HTTP APIs, OpenAPI, authentication, tenancy, and runtime adapters
@hypequery/reactTyped TanStack Query hooks for queries, metrics, and datasets
@hypequery/mcpGoverned ClickHouse tools for Claude, Cursor, and other MCP clients
@hypequery/cliScaffolding, schema generation, local docs, and deployment commands

Choose your starting point

  1. Run npx hypequery init if you want a working project scaffold.
  2. Use @hypequery/clickhouse directly if you only need typed local queries.
  3. Define @hypequery/datasets when analytics meaning is shared.
  4. Add serve(), React hooks, or MCP when the model needs to cross a process boundary.

The progression in code

A query can begin as a local builder chain:

const revenueByRegion = await db
  .table('orders')
  .select(['region'])
  .sum('amount', 'revenue')
  .groupBy('region')
  .execute();

When it becomes reusable business meaning, promote it into the Orders dataset. When it needs an HTTP contract, pass the metric and dataset to Serve:

const { serve } = initServe({
  context: () => ({ db }),
});

export const api = serve({
  queryBuilder: db,
  metrics: { revenue },
  datasets: { orders: Orders },
});

That API can be called in process, over HTTP, from @hypequery/react, or through @hypequery/mcp. The definition and tenant rules stay in one place.

Next steps

On this page