Configuration
Configure the Hypequery MCP server with datasets and a dataset client.
The CLI loads a config file with dynamic import(). The config must export:
datasets: a registry of dataset names to dataset instancesanalytics: a dataset client created withcreateDatasetClient
Minimal config
// mcp-config.mjs
import { createQueryBuilder } from '@hypequery/clickhouse';
import { createDatasetClient } from '@hypequery/datasets';
import { Users } from './datasets/users.js';
const db = createQueryBuilder({
url: process.env.CLICKHOUSE_URL,
username: process.env.CLICKHOUSE_USER,
password: process.env.CLICKHOUSE_PASSWORD,
database: process.env.CLICKHOUSE_DATABASE,
});
export const datasets = {
users: Users,
};
export const analytics = createDatasetClient({ queryBuilder: db });Run it:
npx hypequery-mcp --config ./mcp-config.mjsExpose named metrics
The MCP server can query dataset measures through query_dataset. If you want agents to call stable named KPIs through query_metric, attach metric handles to the dataset registry.
import { publishDatasets } from '@hypequery/datasets';
import { Orders } from './datasets/orders.js';
const revenue = Orders.metric('revenue', { measure: 'revenue' });
const orderCount = Orders.metric('orderCount', { measure: 'orderCount' });
export const datasets = publishDatasets()
.publish(Orders, { metrics: { revenue, orderCount } })
.build();Publish multiple datasets
Chain one publish call per dataset. Metrics are scoped to the dataset they are published with, and alias sets the public registry name when it should differ from the dataset's own name.
import { publishDatasets } from '@hypequery/datasets';
import { Orders } from './datasets/orders.js';
import { Customers } from './datasets/customers.js';
const revenue = Orders.metric('revenue', { measure: 'revenue' });
const orderCount = Orders.metric('orderCount', { measure: 'orderCount' });
const customerCount = Customers.metric('customerCount', { measure: 'customerCount' });
export const datasets = publishDatasets()
.publish(Orders, { metrics: { revenue, orderCount } })
.publish(Customers, { alias: 'accounts', metrics: { customerCount } })
.build();Agents see two datasets, orders and accounts, and three metric tools: query_revenue, query_orderCount, and query_customerCount. Publishing a metric under a dataset that does not own it is rejected at publish time, so customerCount cannot be attached to Orders by mistake.
Related datasets
Relationships follow the alias their target was published under. Because Customers is published as accounts, the customer relationship declared on Orders targets accounts, and agents can select customer.tier against a dataset they can also list on its own. See Relationships.
Publish every dataset that a published dataset relates to. An unpublished target keeps its original name, so the catalog advertises a relationship pointing at a dataset agents cannot list or query.
Metadata for agents
MCP schema introspection exposes dataset, dimension, and metric metadata. Add labels and descriptions where field names alone are ambiguous.
const revenue = Orders.metric('revenue', {
measure: 'revenue',
label: 'Revenue',
description: 'Total completed order revenue.',
});Config path
Use an absolute path when configuring desktop clients. Relative paths depend on the client's launch directory and are a common source of connection failures.
MCP stdio uses stdout for protocol messages. The Hypequery MCP CLI redirects console.log, console.info, and console.debug to stderr so config logs do not corrupt the MCP stream.