> hypequery

Catalog

Export normalized dataset metadata for tools, docs, and agents.

The dataset catalog is a normalized metadata view of a dataset definition. Use it when another runtime needs to inspect the semantic model without reaching into dataset internals.

Catalog metadata includes:

  • source table or view
  • tenant and time keys
  • dimensions and their labels, descriptions, columns, SQL expressions, and filter/group flags
  • measures and their aggregation metadata
  • attached named metrics
  • filters, allowed operators, and filter value types
  • relationship metadata, including whether each relationship is queryable and the qualified field names it contributes
  • dataset limits, maximum result limit, supported time grains, and orderable fields

Dataset catalog

import { getDatasetCatalog } from '@hypequery/datasets';
import { Orders } from './datasets/orders.js';

const catalog = getDatasetCatalog(Orders);

console.log(catalog.dimensions.status);
console.log(catalog.measures.revenue);

The returned object is plain JSON-compatible metadata.

{
  "name": "orders",
  "source": "orders",
  "tenantKey": "tenant_id",
  "timeKey": "created_at",
  "dimensions": {
    "status": {
      "type": "string",
      "column": "status",
      "label": "Status",
      "filterable": true,
      "groupable": true
    }
  },
  "measures": {
    "revenue": {
      "aggregation": "sum",
      "field": "amount",
      "label": "Revenue",
      "filterCount": 0
    }
  },
  "metrics": {},
  "filters": {
    "status": {
      "field": "status",
      "operators": ["eq", "in"],
      "valueType": "string"
    }
  },
  "relationships": {},
  "limits": {
    "maxMeasures": 3,
    "maxResultSize": 1000
  },
  "requiresTenant": true,
  "supportedGrains": ["day", "week", "month", "quarter", "year"],
  "orderableFields": ["status", "revenue", "period"],
  "maxLimit": 1000
}

The full catalog above is a trusted developer/debug view: it intentionally contains physical source, column, SQL, and tenancy details. Do not place it in model context. Use projectAgentSafeCatalog() for agent discovery; it removes those physical details, hides dimensions that are neither filterable nor groupable, and enforces a UTF-8 byte budget over the complete result.

import { projectAgentSafeCatalog } from '@hypequery/datasets';

const safeCatalog = projectAgentSafeCatalog(
  { orders: Orders },
  { maxCatalogBytes: 128 * 1024 },
);

For an authenticated support surface, projectTrustedDebugCatalog() accepts an explicit { authorized: true } proof supplied only after the owning application has made its authorization decision. The trusted projection is not registered as an agent-facing MCP tool.

Agent metadata

Datasets, dimensions, measures, filters, and metrics accept optional examples, synonyms, format, unit, currency, timezone, and sensitivity metadata. Datasets also accept a description, freshness expectation, owner, and safe query defaults:

const Orders = dataset('orders', {
  source: 'analytics.orders',
  description: 'Governed order analytics.',
  examples: ['Revenue by region', 'Weekly order volume'],
  synonyms: ['purchases'],
  timezone: 'UTC',
  freshness: { maxAgeSeconds: 300 },
  owner: 'analytics@example.com',
  sensitivity: 'internal',
  defaults: { dimensions: ['region'], timeGrain: 'week' },
  timeKey: 'createdAt',
  dimensions: {
    createdAt: dimension.timestamp({ format: 'date-time', timezone: 'UTC' }),
    region: dimension.string({ examples: ['EMEA', 'NA'], synonyms: ['market'] }),
  },
});

Metadata is validated and size-bounded when defined, normalized into stable ordering, and carried through semantic contracts and portable deployment contracts. Verified question/answer fixtures are intentionally a separate API.

sensitivity is an advisory label, not an access control. A field marked confidential or restricted is still listed in the agent-safe catalog and is still queryable: nothing filters a catalog or authorizes a query based on this value. Use it to inform reviewers and downstream tooling, and keep deciding what to publish — and who may query it — in your dataset registry and endpoint policy.

Relationship entries carry queryable and fields — the qualified <relationship>.<dimension> names a one-hop query may reference. To-one relationships (belongsTo, hasOne) are queryable; hasMany entries report queryable: false with an empty field list. See Relationships for the query semantics.

When a filter definition does not specify operators, the catalog exposes the default semantic operators from SEMANTIC_FILTER_OPERATORS:

import { SEMANTIC_FILTER_OPERATORS } from '@hypequery/datasets';

console.log(SEMANTIC_FILTER_OPERATORS);
// ["eq", "neq", "gt", "gte", "lt", "lte", "in", "notIn", "between", "like"]

Catalog maps

Use getDatasetCatalogs when you already have a dataset registry.

import { getDatasetCatalogs } from '@hypequery/datasets';
import { Customers, Orders } from './datasets/index.js';

const catalogs = getDatasetCatalogs({
  orders: Orders,
  customers: Customers,
});

Measures vs metrics

Measures are raw aggregations available in dataset queries. Metrics are named KPI handles created with dataset.metric(...).

By default, a dataset instance has measures but does not store every metric ref created from it. Publish named metric refs with a dataset to include them in the catalog.

import { getDatasetCatalog, publishDatasets } from '@hypequery/datasets';

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

const datasets = publishDatasets()
  .publish(Orders, { metrics: { revenue } })
  .build();
const catalog = getDatasetCatalog(datasets.orders);

console.log(catalog.measures.revenue);
console.log(catalog.metrics.revenue);

build() returns the same plain registry shape used by the MCP server. It lets get_dataset_schema show both the exploratory dataset measures and the named metrics that agents should use for stable KPIs. Existing hand-built registry objects remain supported for compatibility.

Current consumers

The catalog is public in @hypequery/datasets. MCP introspection, MCP dataset listing, Serve endpoint descriptions, Serve OpenAPI input schemas, and generated dataset tools use it today to keep metadata aligned with real dataset definitions.

React metadata, CLI-generated labels, and broader cross-package drift tests are planned follow-up work.

For agent and function-calling schemas built from the same catalog, see Tool Generation.

On this page