@hypequery/mcp 0.5.4 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -245
- package/package.json +18 -4
package/README.md
CHANGED
|
@@ -1,293 +1,89 @@
|
|
|
1
1
|
# @hypequery/mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A governed ClickHouse MCP server for AI agents.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
`@hypequery/mcp` turns your hypequery datasets and metrics into Model Context Protocol tools for Claude, Cursor, and other MCP clients. Agents can discover and query approved analytics without receiving unrestricted SQL access or database credentials.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- **Natural Language**: AI-friendly prompts and responses
|
|
9
|
-
- **Type-Safe**: Full TypeScript support with the Hypequery semantic layer
|
|
10
|
-
- **ClickHouse Native**: Optimized for ClickHouse analytics workloads
|
|
11
|
-
|
|
12
|
-
## Installation
|
|
7
|
+
## Install
|
|
13
8
|
|
|
14
9
|
```bash
|
|
15
|
-
npm install @hypequery/mcp
|
|
16
|
-
# or
|
|
17
|
-
pnpm add @hypequery/mcp
|
|
10
|
+
npm install @hypequery/mcp @hypequery/datasets @hypequery/clickhouse
|
|
18
11
|
```
|
|
19
12
|
|
|
20
|
-
##
|
|
21
|
-
|
|
22
|
-
### 1. Create an MCP Config File
|
|
23
|
-
|
|
24
|
-
Create `mcp-config.ts`:
|
|
25
|
-
|
|
26
|
-
```typescript
|
|
27
|
-
import { createDatasetClient } from '@hypequery/datasets';
|
|
28
|
-
import { createQueryBuilder } from '@hypequery/clickhouse';
|
|
29
|
-
import { OrdersDataset, CustomersDataset } from './datasets/index.js';
|
|
30
|
-
|
|
31
|
-
const revenue = OrdersDataset.metric('revenue', { measure: 'revenue' });
|
|
32
|
-
const customerCount = CustomersDataset.metric('customerCount', {
|
|
33
|
-
measure: 'customerCount',
|
|
34
|
-
});
|
|
13
|
+
## Expose your semantic layer
|
|
35
14
|
|
|
36
|
-
|
|
15
|
+
```ts
|
|
16
|
+
// mcp-config.ts
|
|
37
17
|
export const datasets = {
|
|
38
18
|
orders: {
|
|
39
|
-
...
|
|
19
|
+
...Orders,
|
|
40
20
|
metrics: { revenue },
|
|
41
21
|
},
|
|
42
|
-
customers: {
|
|
43
|
-
...CustomersDataset,
|
|
44
|
-
metrics: { customerCount },
|
|
45
|
-
},
|
|
46
22
|
};
|
|
47
23
|
|
|
48
|
-
// Export the semantic runner consumed by the MCP server
|
|
49
|
-
const db = createQueryBuilder({
|
|
50
|
-
url: process.env.CLICKHOUSE_URL,
|
|
51
|
-
username: process.env.CLICKHOUSE_USER,
|
|
52
|
-
password: process.env.CLICKHOUSE_PASSWORD,
|
|
53
|
-
database: process.env.CLICKHOUSE_DATABASE,
|
|
54
|
-
});
|
|
55
|
-
|
|
56
24
|
export const analytics = createDatasetClient({ queryBuilder: db });
|
|
57
25
|
```
|
|
58
26
|
|
|
59
|
-
|
|
27
|
+
Compile the config, then start the stdio server:
|
|
60
28
|
|
|
61
29
|
```bash
|
|
62
|
-
npx hypequery-mcp --config
|
|
30
|
+
npx hypequery-mcp --config /absolute/path/to/mcp-config.js
|
|
63
31
|
```
|
|
64
32
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):
|
|
33
|
+
Add it to an MCP client:
|
|
68
34
|
|
|
69
35
|
```json
|
|
70
36
|
{
|
|
71
37
|
"mcpServers": {
|
|
72
|
-
"hypequery": {
|
|
38
|
+
"hypequery-clickhouse": {
|
|
73
39
|
"command": "npx",
|
|
74
|
-
"args": [
|
|
40
|
+
"args": [
|
|
41
|
+
"hypequery-mcp",
|
|
42
|
+
"--config",
|
|
43
|
+
"/absolute/path/to/mcp-config.js"
|
|
44
|
+
]
|
|
75
45
|
}
|
|
76
46
|
}
|
|
77
47
|
}
|
|
78
48
|
```
|
|
79
49
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
Now you can ask Claude to query your data:
|
|
83
|
-
|
|
84
|
-
> "Show me revenue by region for the last month"
|
|
85
|
-
|
|
86
|
-
> "What are the top 10 customers by order count?"
|
|
87
|
-
|
|
88
|
-
> "List all available datasets"
|
|
89
|
-
|
|
90
|
-
## Available Tools
|
|
91
|
-
|
|
92
|
-
### `list_datasets`
|
|
93
|
-
|
|
94
|
-
Lists all available datasets with their descriptions.
|
|
95
|
-
|
|
96
|
-
**Example:**
|
|
97
|
-
```typescript
|
|
98
|
-
{
|
|
99
|
-
"name": "list_datasets"
|
|
100
|
-
}
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
**Response:**
|
|
104
|
-
```json
|
|
105
|
-
{
|
|
106
|
-
"datasets": [
|
|
107
|
-
{
|
|
108
|
-
"name": "orders",
|
|
109
|
-
"description": "Customer orders and revenue data",
|
|
110
|
-
"dimensionCount": 5,
|
|
111
|
-
"measureCount": 4,
|
|
112
|
-
"metricCount": 4
|
|
113
|
-
}
|
|
114
|
-
],
|
|
115
|
-
"total": 1
|
|
116
|
-
}
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
### `get_dataset_schema`
|
|
50
|
+
Now an agent can ask, “Show revenue by region for the last month,” using the same metric definition as your backend and dashboard.
|
|
120
51
|
|
|
121
|
-
|
|
52
|
+
## Tools agents receive
|
|
122
53
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
"arguments": {
|
|
128
|
-
"dataset": "orders"
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
```
|
|
54
|
+
- `list_datasets` discovers available analytics models;
|
|
55
|
+
- `get_dataset_schema` explains dimensions, measures, metrics, and relationships;
|
|
56
|
+
- `query_metric` executes named KPIs;
|
|
57
|
+
- `query_dataset` explores the fields you chose to publish.
|
|
132
58
|
|
|
133
|
-
|
|
134
|
-
```json
|
|
135
|
-
{
|
|
136
|
-
"name": "orders",
|
|
137
|
-
"dimensions": {
|
|
138
|
-
"region": { "type": "string", "label": "Region" },
|
|
139
|
-
"status": { "type": "string", "label": "Order Status" }
|
|
140
|
-
},
|
|
141
|
-
"measures": {
|
|
142
|
-
"revenue": { "aggregation": "sum", "field": "amount", "label": "Revenue" },
|
|
143
|
-
"orderCount": { "aggregation": "count", "field": "id", "label": "Order Count" }
|
|
144
|
-
},
|
|
145
|
-
"metrics": {
|
|
146
|
-
"totalRevenue": { "type": "metric", "aggregation": "revenue", "label": "Total Revenue" }
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
```
|
|
59
|
+
## Safer than raw SQL access
|
|
150
60
|
|
|
151
|
-
|
|
61
|
+
- Tool schemas come from your TypeScript semantic layer.
|
|
62
|
+
- Filters, fields, ordering, and limits are validated.
|
|
63
|
+
- ClickHouse credentials remain in the server process.
|
|
64
|
+
- SQL text stays hidden by default.
|
|
65
|
+
- Tenant identity comes from trusted host configuration, never the prompt.
|
|
152
66
|
|
|
153
|
-
|
|
67
|
+
For tenant-scoped datasets, run the server programmatically with the trusted tenant ID:
|
|
154
68
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
{
|
|
158
|
-
"name": "query_metric",
|
|
159
|
-
"arguments": {
|
|
160
|
-
"dataset": "orders",
|
|
161
|
-
"metric": "revenue",
|
|
162
|
-
"dimensions": ["region"],
|
|
163
|
-
"filters": [
|
|
164
|
-
{ "field": "status", "operator": "eq", "value": "completed" }
|
|
165
|
-
],
|
|
166
|
-
"grain": "month",
|
|
167
|
-
"orderBy": [
|
|
168
|
-
{ "field": "revenue", "direction": "desc" }
|
|
169
|
-
],
|
|
170
|
-
"limit": 10
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
**Response:**
|
|
176
|
-
```json
|
|
177
|
-
{
|
|
178
|
-
"data": [
|
|
179
|
-
{ "region": "US", "month": "2024-01", "revenue": 125000 },
|
|
180
|
-
{ "region": "EU", "month": "2024-01", "revenue": 98000 }
|
|
181
|
-
],
|
|
182
|
-
"meta": {
|
|
183
|
-
"sql": "SELECT...",
|
|
184
|
-
"timingMs": 45,
|
|
185
|
-
"rowCount": 2
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
### `query_dataset`
|
|
191
|
-
|
|
192
|
-
Executes an ad-hoc dataset query with custom dimensions and measures.
|
|
193
|
-
|
|
194
|
-
**Example:**
|
|
195
|
-
```typescript
|
|
196
|
-
{
|
|
197
|
-
"name": "query_dataset",
|
|
198
|
-
"arguments": {
|
|
199
|
-
"dataset": "orders",
|
|
200
|
-
"dimensions": ["region", "status"],
|
|
201
|
-
"measures": ["revenue", "orderCount"],
|
|
202
|
-
"limit": 100
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
## Programmatic Usage
|
|
208
|
-
|
|
209
|
-
You can also use the MCP server programmatically in your application:
|
|
210
|
-
|
|
211
|
-
```typescript
|
|
212
|
-
import { createMCPServer } from '@hypequery/mcp';
|
|
213
|
-
import { createDatasetClient } from '@hypequery/datasets';
|
|
214
|
-
import { datasets } from './datasets/index.js';
|
|
215
|
-
|
|
216
|
-
const analytics = createDatasetClient({
|
|
217
|
-
url: process.env.CLICKHOUSE_URL,
|
|
218
|
-
username: process.env.CLICKHOUSE_USER,
|
|
219
|
-
password: process.env.CLICKHOUSE_PASSWORD,
|
|
220
|
-
database: process.env.CLICKHOUSE_DATABASE,
|
|
221
|
-
});
|
|
222
|
-
|
|
223
|
-
const server = await createMCPServer({
|
|
69
|
+
```ts
|
|
70
|
+
await createMCPServer({
|
|
224
71
|
datasets,
|
|
225
72
|
analytics,
|
|
226
|
-
name: '
|
|
73
|
+
name: 'acme-analytics',
|
|
227
74
|
version: '1.0.0',
|
|
75
|
+
tenantId: session.accountId,
|
|
228
76
|
});
|
|
229
|
-
|
|
230
|
-
// Server is now running via stdio transport
|
|
231
77
|
```
|
|
232
78
|
|
|
233
|
-
##
|
|
234
|
-
|
|
235
|
-
- `eq`: Equal to
|
|
236
|
-
- `neq`: Not equal to
|
|
237
|
-
- `gt`: Greater than
|
|
238
|
-
- `gte`: Greater than or equal to
|
|
239
|
-
- `lt`: Less than
|
|
240
|
-
- `lte`: Less than or equal to
|
|
241
|
-
- `in`: In list
|
|
242
|
-
- `notIn`: Not in list
|
|
243
|
-
- `between`: Between two values
|
|
244
|
-
- `like`: Pattern match (SQL LIKE)
|
|
245
|
-
|
|
246
|
-
## Time Grains
|
|
247
|
-
|
|
248
|
-
- `day`: Daily aggregation
|
|
249
|
-
- `week`: Weekly aggregation
|
|
250
|
-
- `month`: Monthly aggregation
|
|
251
|
-
- `quarter`: Quarterly aggregation
|
|
252
|
-
- `year`: Yearly aggregation
|
|
253
|
-
|
|
254
|
-
## Prompts
|
|
255
|
-
|
|
256
|
-
The MCP server also exposes a `dataset_guide` prompt that provides natural language guidance for querying datasets.
|
|
257
|
-
|
|
258
|
-
## Environment Variables
|
|
259
|
-
|
|
260
|
-
Your config file can use environment variables for database credentials:
|
|
261
|
-
|
|
262
|
-
```typescript
|
|
263
|
-
const analytics = createDatasetClient({
|
|
264
|
-
url: process.env.CLICKHOUSE_URL || 'http://localhost:8123',
|
|
265
|
-
username: process.env.CLICKHOUSE_USER || 'default',
|
|
266
|
-
password: process.env.CLICKHOUSE_PASSWORD,
|
|
267
|
-
database: process.env.CLICKHOUSE_DATABASE || 'default',
|
|
268
|
-
});
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
## Troubleshooting
|
|
272
|
-
|
|
273
|
-
### MCP server not connecting
|
|
274
|
-
|
|
275
|
-
1. Check that the config file path is absolute, not relative
|
|
276
|
-
2. Ensure the config file exports both `datasets` and `analytics`
|
|
277
|
-
3. Check Claude Desktop logs for errors
|
|
278
|
-
|
|
279
|
-
### Queries failing
|
|
280
|
-
|
|
281
|
-
1. Verify your ClickHouse connection is working
|
|
282
|
-
2. Check that dataset definitions match your database schema
|
|
283
|
-
3. For trusted local debugging, start the programmatic server with `includeSql: true` and inspect `meta.sql` in responses
|
|
284
|
-
|
|
285
|
-
## Related Packages
|
|
79
|
+
## Learn more
|
|
286
80
|
|
|
287
|
-
-
|
|
288
|
-
-
|
|
289
|
-
-
|
|
81
|
+
- [ClickHouse MCP overview](https://hypequery.com/clickhouse-mcp)
|
|
82
|
+
- [MCP configuration](https://hypequery.com/docs/mcp/configuration)
|
|
83
|
+
- [MCP tools](https://hypequery.com/docs/mcp/tools)
|
|
84
|
+
- [MCP safety](https://hypequery.com/docs/mcp/safety)
|
|
85
|
+
- [Current capabilities](https://hypequery.com/docs/capabilities)
|
|
290
86
|
|
|
291
87
|
## License
|
|
292
88
|
|
|
293
|
-
Apache-2.0
|
|
89
|
+
Apache-2.0.
|
package/package.json
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hypequery/mcp",
|
|
3
|
-
"version": "0.5.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.5.5",
|
|
4
|
+
"description": "Governed ClickHouse MCP server for semantic metrics, datasets, Claude, Cursor, and AI agents",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"mcp",
|
|
7
|
+
"model-context-protocol",
|
|
8
|
+
"clickhouse",
|
|
9
|
+
"semantic-layer",
|
|
10
|
+
"analytics",
|
|
11
|
+
"query-builder",
|
|
12
|
+
"orm",
|
|
13
|
+
"ai-agents",
|
|
14
|
+
"claude",
|
|
15
|
+
"cursor",
|
|
16
|
+
"typescript"
|
|
17
|
+
],
|
|
5
18
|
"license": "Apache-2.0",
|
|
6
19
|
"type": "module",
|
|
7
20
|
"main": "dist/index.js",
|
|
@@ -20,7 +33,7 @@
|
|
|
20
33
|
"dist"
|
|
21
34
|
],
|
|
22
35
|
"dependencies": {
|
|
23
|
-
"@hypequery/datasets": "^0.13.
|
|
36
|
+
"@hypequery/datasets": "^0.13.3",
|
|
24
37
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
25
38
|
"zod": "^3.23.8"
|
|
26
39
|
},
|
|
@@ -31,7 +44,8 @@
|
|
|
31
44
|
},
|
|
32
45
|
"repository": {
|
|
33
46
|
"type": "git",
|
|
34
|
-
"url": "https://github.com/hypequery/hypequery.git"
|
|
47
|
+
"url": "git+https://github.com/hypequery/hypequery.git",
|
|
48
|
+
"directory": "packages/mcp-server"
|
|
35
49
|
},
|
|
36
50
|
"homepage": "https://hypequery.com",
|
|
37
51
|
"bugs": {
|