@hypequery/mcp 0.5.5 → 0.7.0
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 +83 -6
- package/dist/api.type-test.d.ts +2 -0
- package/dist/api.type-test.d.ts.map +1 -0
- package/dist/api.type-test.js +14 -0
- package/dist/bin.js +2 -1
- package/dist/discovery-executor.d.ts +78 -0
- package/dist/discovery-executor.d.ts.map +1 -0
- package/dist/discovery-executor.js +111 -0
- package/dist/errors.d.ts +29 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +65 -0
- package/dist/executor.d.ts +50 -0
- package/dist/executor.d.ts.map +1 -0
- package/dist/executor.js +103 -0
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -2
- package/dist/protocol-server.d.ts +26 -0
- package/dist/protocol-server.d.ts.map +1 -0
- package/dist/protocol-server.js +48 -0
- package/dist/server.d.ts +15 -44
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +21 -271
- package/dist/stdio.d.ts +8 -0
- package/dist/stdio.d.ts.map +1 -0
- package/dist/stdio.js +14 -0
- package/dist/tools/args.d.ts +16 -16
- package/dist/tools/args.d.ts.map +1 -1
- package/dist/tools/args.js +9 -8
- package/dist/tools/introspect.d.ts +8 -6
- package/dist/tools/introspect.d.ts.map +1 -1
- package/dist/tools/introspect.js +45 -168
- package/dist/tools/list-datasets.d.ts.map +1 -1
- package/dist/tools/list-datasets.js +2 -8
- package/dist/tools/query-dataset.d.ts.map +1 -1
- package/dist/tools/query-dataset.js +26 -30
- package/dist/tools/query-metric.d.ts.map +1 -1
- package/dist/tools/query-metric.js +27 -31
- package/dist/tools/tool-manifest.d.ts +28 -0
- package/dist/tools/tool-manifest.d.ts.map +1 -0
- package/dist/tools/tool-manifest.js +302 -0
- package/dist/tools/utils/canonical-query-schemas.d.ts +17 -0
- package/dist/tools/utils/canonical-query-schemas.d.ts.map +1 -0
- package/dist/tools/utils/canonical-query-schemas.js +131 -0
- package/dist/tools/utils/execution-budget.d.ts +11 -0
- package/dist/tools/utils/execution-budget.d.ts.map +1 -0
- package/dist/tools/utils/execution-budget.js +71 -0
- package/dist/tools/utils/legacy-agent-catalog.d.ts +19 -0
- package/dist/tools/utils/legacy-agent-catalog.d.ts.map +1 -0
- package/dist/tools/utils/legacy-agent-catalog.js +171 -0
- package/dist/tools/utils/query-limits.d.ts +25 -0
- package/dist/tools/utils/query-limits.d.ts.map +1 -0
- package/dist/tools/utils/query-limits.js +69 -0
- package/dist/tools/utils/query-result.d.ts +4 -0
- package/dist/tools/utils/query-result.d.ts.map +1 -0
- package/dist/tools/utils/query-result.js +19 -0
- package/dist/tools/utils/query-schema.d.ts +8 -0
- package/dist/tools/utils/query-schema.d.ts.map +1 -0
- package/dist/tools/utils/query-schema.js +36 -0
- package/dist/tools/utils/tool-response.d.ts +6 -0
- package/dist/tools/utils/tool-response.d.ts.map +1 -0
- package/dist/tools/utils/tool-response.js +33 -0
- package/dist/types.d.ts +54 -58
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +9 -0
- package/dist/utils/tenant-config.d.ts +3 -0
- package/dist/utils/tenant-config.d.ts.map +1 -0
- package/dist/utils/tenant-config.js +23 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +5 -0
- package/package.json +7 -3
package/dist/index.js
CHANGED
|
@@ -5,9 +5,15 @@
|
|
|
5
5
|
* Exposes datasets and metrics to AI agents via MCP tools.
|
|
6
6
|
*/
|
|
7
7
|
export { HypequeryMCPServer, createMCPServer } from './server.js';
|
|
8
|
+
export { HypequeryMCPExecutor, createMCPExecutor, } from './executor.js';
|
|
9
|
+
export { HypequeryMCPDiscoveryExecutor, createMCPDiscoveryExecutor, } from './discovery-executor.js';
|
|
10
|
+
export { HypequeryMCPProtocolServer, createMCPProtocolServer, } from './protocol-server.js';
|
|
11
|
+
export { connectMCPServerStdio, startStdioMCPServer } from './stdio.js';
|
|
8
12
|
export { listDatasetsTool } from './tools/list-datasets.js';
|
|
9
|
-
export { getDatasetSchemaTool } from './tools/introspect.js';
|
|
13
|
+
export { getDatasetSchemaTool, getTrustedDatasetSchema } from './tools/introspect.js';
|
|
10
14
|
export { queryMetricTool } from './tools/query-metric.js';
|
|
11
15
|
export { queryDatasetTool } from './tools/query-dataset.js';
|
|
12
16
|
export { datasetGuidePrompt } from './prompts/dataset-guide.js';
|
|
13
|
-
export {
|
|
17
|
+
export { MCPExecutionBudgetError, MCPToolError, classifyMCPToolError, formatMCPToolError, } from './errors.js';
|
|
18
|
+
export { MAX_QUERY_LIMIT, DEFAULT_QUERY_LIMIT, MAX_QUERY_OFFSET, MAX_QUERY_DIMENSIONS, MAX_QUERY_MEASURES, MAX_QUERY_FILTERS, MAX_QUERY_ORDER_BY, DEFAULT_QUERY_TIMEOUT_MS, MAX_QUERY_TIMEOUT_MS, DEFAULT_RESPONSE_BYTES, MAX_RESPONSE_BYTES, } from './types.js';
|
|
19
|
+
export { MCP_PACKAGE_VERSION } from './version.js';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
|
2
|
+
import type { MCPToolExecutor } from './executor.js';
|
|
3
|
+
export interface MCPProtocolServerOptions {
|
|
4
|
+
executor: MCPToolExecutor;
|
|
5
|
+
name?: string;
|
|
6
|
+
version?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* MCP protocol adapter for a transport-neutral Hypequery executor.
|
|
10
|
+
*
|
|
11
|
+
* The caller owns the transport. The same server can therefore be connected to
|
|
12
|
+
* stdio, an in-memory pair, or a hosted transport without changing tool logic.
|
|
13
|
+
*/
|
|
14
|
+
export declare class HypequeryMCPProtocolServer {
|
|
15
|
+
private readonly server;
|
|
16
|
+
protected readonly executor: MCPToolExecutor;
|
|
17
|
+
constructor(options: MCPProtocolServerOptions);
|
|
18
|
+
private setupHandlers;
|
|
19
|
+
getManifestHash(): string;
|
|
20
|
+
connect(transport: Transport): Promise<void>;
|
|
21
|
+
close(): Promise<void>;
|
|
22
|
+
/** Alias retained for the existing Hypequery MCP server lifecycle. */
|
|
23
|
+
stop(): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
export declare function createMCPProtocolServer(options: MCPProtocolServerOptions): HypequeryMCPProtocolServer;
|
|
26
|
+
//# sourceMappingURL=protocol-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol-server.d.ts","sourceRoot":"","sources":["../src/protocol-server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAO/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGrD,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,eAAe,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,qBAAa,0BAA0B;IACrC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;gBAEjC,OAAO,EAAE,wBAAwB;IAkB7C,OAAO,CAAC,aAAa;IAkBrB,eAAe,IAAI,MAAM;IAInB,OAAO,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,sEAAsE;IAChE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5B;AAED,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,wBAAwB,GAChC,0BAA0B,CAE5B"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
|
+
import { CallToolRequestSchema, GetPromptRequestSchema, ListPromptsRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import { MCP_PACKAGE_VERSION } from './version.js';
|
|
4
|
+
/**
|
|
5
|
+
* MCP protocol adapter for a transport-neutral Hypequery executor.
|
|
6
|
+
*
|
|
7
|
+
* The caller owns the transport. The same server can therefore be connected to
|
|
8
|
+
* stdio, an in-memory pair, or a hosted transport without changing tool logic.
|
|
9
|
+
*/
|
|
10
|
+
export class HypequeryMCPProtocolServer {
|
|
11
|
+
server;
|
|
12
|
+
executor;
|
|
13
|
+
constructor(options) {
|
|
14
|
+
this.executor = options.executor;
|
|
15
|
+
this.server = new Server({
|
|
16
|
+
name: options.name ?? 'hypequery-mcp-server',
|
|
17
|
+
version: options.version ?? MCP_PACKAGE_VERSION,
|
|
18
|
+
}, {
|
|
19
|
+
capabilities: {
|
|
20
|
+
tools: {},
|
|
21
|
+
prompts: {},
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
this.setupHandlers();
|
|
25
|
+
}
|
|
26
|
+
setupHandlers() {
|
|
27
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => (this.executor.listTools()));
|
|
28
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request, extra) => (this.executor.callTool(request.params.name, request.params.arguments, extra?.signal)));
|
|
29
|
+
this.server.setRequestHandler(ListPromptsRequestSchema, async () => (this.executor.listPrompts()));
|
|
30
|
+
this.server.setRequestHandler(GetPromptRequestSchema, async (request) => (this.executor.getPrompt(request.params.name, request.params.arguments)));
|
|
31
|
+
}
|
|
32
|
+
getManifestHash() {
|
|
33
|
+
return this.executor.getManifestHash();
|
|
34
|
+
}
|
|
35
|
+
async connect(transport) {
|
|
36
|
+
await this.server.connect(transport);
|
|
37
|
+
}
|
|
38
|
+
async close() {
|
|
39
|
+
await this.server.close();
|
|
40
|
+
}
|
|
41
|
+
/** Alias retained for the existing Hypequery MCP server lifecycle. */
|
|
42
|
+
async stop() {
|
|
43
|
+
await this.close();
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
export function createMCPProtocolServer(options) {
|
|
47
|
+
return new HypequeryMCPProtocolServer(options);
|
|
48
|
+
}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,56 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Backwards-compatible Hypequery MCP server facade.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* New integrations can compose HypequeryMCPExecutor with
|
|
5
|
+
* HypequeryMCPProtocolServer and supply their own transport. Existing callers
|
|
6
|
+
* can continue to construct this class and call start() for stdio.
|
|
6
7
|
*/
|
|
7
|
-
import type
|
|
8
|
-
import
|
|
9
|
-
export
|
|
10
|
-
|
|
11
|
-
* Dataset registry - map of dataset names to instances
|
|
12
|
-
*/
|
|
13
|
-
datasets: DatasetRegistry;
|
|
14
|
-
/**
|
|
15
|
-
* Semantic analytics for running metric and dataset queries
|
|
16
|
-
*/
|
|
17
|
-
analytics: DatasetClient;
|
|
18
|
-
/**
|
|
19
|
-
* Server name (shown in MCP client)
|
|
20
|
-
*/
|
|
21
|
-
name?: string;
|
|
22
|
-
/**
|
|
23
|
-
* Server version
|
|
24
|
-
*/
|
|
25
|
-
version?: string;
|
|
26
|
-
/**
|
|
27
|
-
* Trusted tenant id used to scope tenant-keyed datasets.
|
|
28
|
-
*/
|
|
29
|
-
tenantId?: string;
|
|
30
|
-
/**
|
|
31
|
-
* Include generated SQL in query tool responses.
|
|
32
|
-
*
|
|
33
|
-
* Defaults to false so agent-facing responses do not expose SQL text unless
|
|
34
|
-
* explicitly enabled for trusted debugging.
|
|
35
|
-
*/
|
|
36
|
-
includeSql?: boolean;
|
|
37
|
-
}
|
|
38
|
-
export declare class HypequeryMCPServer {
|
|
39
|
-
private server;
|
|
40
|
-
private config;
|
|
8
|
+
import { type MCPServerConfig } from './executor.js';
|
|
9
|
+
import { HypequeryMCPProtocolServer } from './protocol-server.js';
|
|
10
|
+
export type { MCPServerConfig } from './executor.js';
|
|
11
|
+
export declare class HypequeryMCPServer extends HypequeryMCPProtocolServer {
|
|
41
12
|
constructor(config: MCPServerConfig);
|
|
42
|
-
private setupHandlers;
|
|
43
13
|
/**
|
|
44
|
-
* Start the
|
|
14
|
+
* Start with the legacy stdio transport.
|
|
15
|
+
*
|
|
16
|
+
* @deprecated Prefer connect(transport) or startStdioMCPServer(config).
|
|
45
17
|
*/
|
|
46
18
|
start(): Promise<void>;
|
|
47
|
-
/**
|
|
48
|
-
* Stop the MCP server
|
|
49
|
-
*/
|
|
50
|
-
stop(): Promise<void>;
|
|
51
19
|
}
|
|
52
20
|
/**
|
|
53
|
-
* Create and start
|
|
21
|
+
* Create and start a backwards-compatible stdio MCP server.
|
|
22
|
+
*
|
|
23
|
+
* @deprecated Prefer createMCPExecutor with createMCPProtocolServer, or
|
|
24
|
+
* startStdioMCPServer for an explicit stdio lifecycle.
|
|
54
25
|
*/
|
|
55
26
|
export declare function createMCPServer(config: MCPServerConfig): Promise<HypequeryMCPServer>;
|
|
56
27
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAElE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,qBAAa,kBAAmB,SAAQ,0BAA0B;gBACpD,MAAM,EAAE,eAAe;IASnC;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAI7B;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAI1F"}
|
package/dist/server.js
CHANGED
|
@@ -1,286 +1,36 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Backwards-compatible Hypequery MCP server facade.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* New integrations can compose HypequeryMCPExecutor with
|
|
5
|
+
* HypequeryMCPProtocolServer and supply their own transport. Existing callers
|
|
6
|
+
* can continue to construct this class and call start() for stdio.
|
|
6
7
|
*/
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
import { listDatasetsTool } from './tools/list-datasets.js';
|
|
11
|
-
import { getDatasetSchemaTool } from './tools/introspect.js';
|
|
12
|
-
import { queryMetricTool } from './tools/query-metric.js';
|
|
13
|
-
import { queryDatasetTool } from './tools/query-dataset.js';
|
|
14
|
-
import { datasetGuidePrompt } from './prompts/dataset-guide.js';
|
|
15
|
-
function isRecord(value) {
|
|
16
|
-
return !!value && typeof value === 'object';
|
|
17
|
-
}
|
|
18
|
-
function getTenantKey(dataset) {
|
|
19
|
-
if (!isRecord(dataset)) {
|
|
20
|
-
return undefined;
|
|
21
|
-
}
|
|
22
|
-
const config = dataset.config;
|
|
23
|
-
const configTenantKey = isRecord(config) ? config.tenantKey : undefined;
|
|
24
|
-
const tenantKey = dataset.tenantKey ?? configTenantKey;
|
|
25
|
-
return typeof tenantKey === 'string' && tenantKey.length > 0 ? tenantKey : undefined;
|
|
26
|
-
}
|
|
27
|
-
function validateTenantConfig(config) {
|
|
28
|
-
if (config.tenantId) {
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
const tenantScopedDatasets = Object.entries(config.datasets ?? {})
|
|
32
|
-
.filter(([, ds]) => getTenantKey(ds))
|
|
33
|
-
.map(([name]) => name);
|
|
34
|
-
if (tenantScopedDatasets.length > 0) {
|
|
35
|
-
throw new Error(`MCP server tenantId is required for tenant-scoped datasets: ${tenantScopedDatasets.join(', ')}`);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
export class HypequeryMCPServer {
|
|
39
|
-
server;
|
|
40
|
-
config;
|
|
8
|
+
import { HypequeryMCPExecutor } from './executor.js';
|
|
9
|
+
import { HypequeryMCPProtocolServer } from './protocol-server.js';
|
|
10
|
+
export class HypequeryMCPServer extends HypequeryMCPProtocolServer {
|
|
41
11
|
constructor(config) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
name: config.name
|
|
46
|
-
version: config.version
|
|
47
|
-
}, {
|
|
48
|
-
capabilities: {
|
|
49
|
-
tools: {},
|
|
50
|
-
prompts: {},
|
|
51
|
-
},
|
|
52
|
-
});
|
|
53
|
-
this.setupHandlers();
|
|
54
|
-
}
|
|
55
|
-
setupHandlers() {
|
|
56
|
-
// List available tools
|
|
57
|
-
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
58
|
-
tools: [
|
|
59
|
-
{
|
|
60
|
-
name: 'list_datasets',
|
|
61
|
-
description: 'List all available datasets in the semantic layer',
|
|
62
|
-
inputSchema: {
|
|
63
|
-
type: 'object',
|
|
64
|
-
properties: {},
|
|
65
|
-
},
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
name: 'get_dataset_schema',
|
|
69
|
-
description: 'Get the schema (dimensions, measures, named metrics, filters, relationships) for a specific dataset',
|
|
70
|
-
inputSchema: {
|
|
71
|
-
type: 'object',
|
|
72
|
-
properties: {
|
|
73
|
-
dataset: {
|
|
74
|
-
type: 'string',
|
|
75
|
-
description: 'Name of the dataset to introspect',
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
required: ['dataset'],
|
|
79
|
-
},
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
name: 'query_metric',
|
|
83
|
-
description: 'Execute a metric query with optional dimensions, filters, time grain, and sorting',
|
|
84
|
-
inputSchema: {
|
|
85
|
-
type: 'object',
|
|
86
|
-
properties: {
|
|
87
|
-
dataset: {
|
|
88
|
-
type: 'string',
|
|
89
|
-
description: 'Name of the dataset containing the metric',
|
|
90
|
-
},
|
|
91
|
-
metric: {
|
|
92
|
-
type: 'string',
|
|
93
|
-
description: 'Name of the metric to query',
|
|
94
|
-
},
|
|
95
|
-
dimensions: {
|
|
96
|
-
type: 'array',
|
|
97
|
-
items: { type: 'string' },
|
|
98
|
-
description: 'Dimensions to group by (optional)',
|
|
99
|
-
},
|
|
100
|
-
filters: {
|
|
101
|
-
type: 'array',
|
|
102
|
-
items: {
|
|
103
|
-
type: 'object',
|
|
104
|
-
properties: {
|
|
105
|
-
field: { type: 'string' },
|
|
106
|
-
operator: {
|
|
107
|
-
type: 'string',
|
|
108
|
-
enum: ['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'in', 'notIn', 'between', 'like']
|
|
109
|
-
},
|
|
110
|
-
value: {},
|
|
111
|
-
},
|
|
112
|
-
required: ['field', 'operator', 'value'],
|
|
113
|
-
},
|
|
114
|
-
description: 'Filters to apply (optional)',
|
|
115
|
-
},
|
|
116
|
-
grain: {
|
|
117
|
-
type: 'string',
|
|
118
|
-
enum: ['day', 'week', 'month', 'quarter', 'year'],
|
|
119
|
-
description: 'Time grain for time-series queries (optional)',
|
|
120
|
-
},
|
|
121
|
-
orderBy: {
|
|
122
|
-
type: 'array',
|
|
123
|
-
items: {
|
|
124
|
-
type: 'object',
|
|
125
|
-
properties: {
|
|
126
|
-
field: { type: 'string' },
|
|
127
|
-
direction: { type: 'string', enum: ['asc', 'desc'] },
|
|
128
|
-
},
|
|
129
|
-
required: ['field', 'direction'],
|
|
130
|
-
},
|
|
131
|
-
description: 'Sort order (optional)',
|
|
132
|
-
},
|
|
133
|
-
limit: {
|
|
134
|
-
type: 'number',
|
|
135
|
-
description: 'Maximum number of rows to return (optional)',
|
|
136
|
-
},
|
|
137
|
-
offset: {
|
|
138
|
-
type: 'number',
|
|
139
|
-
description: 'Number of rows to skip before returning results (optional)',
|
|
140
|
-
},
|
|
141
|
-
},
|
|
142
|
-
required: ['dataset', 'metric'],
|
|
143
|
-
},
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
name: 'query_dataset',
|
|
147
|
-
description: 'Execute an ad-hoc dataset query with custom dimensions and measures',
|
|
148
|
-
inputSchema: {
|
|
149
|
-
type: 'object',
|
|
150
|
-
properties: {
|
|
151
|
-
dataset: {
|
|
152
|
-
type: 'string',
|
|
153
|
-
description: 'Name of the dataset to query',
|
|
154
|
-
},
|
|
155
|
-
dimensions: {
|
|
156
|
-
type: 'array',
|
|
157
|
-
items: { type: 'string' },
|
|
158
|
-
description: 'Dimensions to select',
|
|
159
|
-
},
|
|
160
|
-
measures: {
|
|
161
|
-
type: 'array',
|
|
162
|
-
items: { type: 'string' },
|
|
163
|
-
description: 'Measures to calculate',
|
|
164
|
-
},
|
|
165
|
-
filters: {
|
|
166
|
-
type: 'array',
|
|
167
|
-
items: {
|
|
168
|
-
type: 'object',
|
|
169
|
-
properties: {
|
|
170
|
-
field: { type: 'string' },
|
|
171
|
-
operator: {
|
|
172
|
-
type: 'string',
|
|
173
|
-
enum: ['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'in', 'notIn', 'between', 'like']
|
|
174
|
-
},
|
|
175
|
-
value: {},
|
|
176
|
-
},
|
|
177
|
-
required: ['field', 'operator', 'value'],
|
|
178
|
-
},
|
|
179
|
-
description: 'Filters to apply (optional)',
|
|
180
|
-
},
|
|
181
|
-
grain: {
|
|
182
|
-
type: 'string',
|
|
183
|
-
enum: ['day', 'week', 'month', 'quarter', 'year'],
|
|
184
|
-
description: 'Time grain for time-series queries (optional)',
|
|
185
|
-
},
|
|
186
|
-
orderBy: {
|
|
187
|
-
type: 'array',
|
|
188
|
-
items: {
|
|
189
|
-
type: 'object',
|
|
190
|
-
properties: {
|
|
191
|
-
field: { type: 'string' },
|
|
192
|
-
direction: { type: 'string', enum: ['asc', 'desc'] },
|
|
193
|
-
},
|
|
194
|
-
required: ['field', 'direction'],
|
|
195
|
-
},
|
|
196
|
-
description: 'Sort order (optional)',
|
|
197
|
-
},
|
|
198
|
-
limit: {
|
|
199
|
-
type: 'number',
|
|
200
|
-
description: 'Maximum number of rows to return (optional)',
|
|
201
|
-
},
|
|
202
|
-
offset: {
|
|
203
|
-
type: 'number',
|
|
204
|
-
description: 'Number of rows to skip before returning results (optional)',
|
|
205
|
-
},
|
|
206
|
-
},
|
|
207
|
-
required: ['dataset'],
|
|
208
|
-
},
|
|
209
|
-
},
|
|
210
|
-
],
|
|
211
|
-
}));
|
|
212
|
-
// Handle tool calls
|
|
213
|
-
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
214
|
-
const { name, arguments: args } = request.params;
|
|
215
|
-
try {
|
|
216
|
-
switch (name) {
|
|
217
|
-
case 'list_datasets':
|
|
218
|
-
return await listDatasetsTool(this.config.datasets);
|
|
219
|
-
case 'get_dataset_schema':
|
|
220
|
-
return await getDatasetSchemaTool(this.config.datasets, args, { includeSql: this.config.includeSql });
|
|
221
|
-
case 'query_metric':
|
|
222
|
-
return await queryMetricTool(this.config.datasets, this.config.analytics, args, { tenantId: this.config.tenantId, includeSql: this.config.includeSql });
|
|
223
|
-
case 'query_dataset':
|
|
224
|
-
return await queryDatasetTool(this.config.datasets, this.config.analytics, args, { tenantId: this.config.tenantId, includeSql: this.config.includeSql });
|
|
225
|
-
default:
|
|
226
|
-
throw new Error(`Unknown tool: ${name}`);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
catch (error) {
|
|
230
|
-
return {
|
|
231
|
-
content: [
|
|
232
|
-
{
|
|
233
|
-
type: 'text',
|
|
234
|
-
text: `Error: ${error instanceof Error ? error.message : String(error)}`,
|
|
235
|
-
},
|
|
236
|
-
],
|
|
237
|
-
isError: true,
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
});
|
|
241
|
-
// List available prompts
|
|
242
|
-
this.server.setRequestHandler(ListPromptsRequestSchema, async () => ({
|
|
243
|
-
prompts: [
|
|
244
|
-
{
|
|
245
|
-
name: 'dataset_guide',
|
|
246
|
-
description: 'Guide for querying datasets with natural language',
|
|
247
|
-
arguments: [
|
|
248
|
-
{
|
|
249
|
-
name: 'dataset',
|
|
250
|
-
description: 'Name of the dataset to get guidance for',
|
|
251
|
-
required: false,
|
|
252
|
-
},
|
|
253
|
-
],
|
|
254
|
-
},
|
|
255
|
-
],
|
|
256
|
-
}));
|
|
257
|
-
// Get prompt content
|
|
258
|
-
this.server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
259
|
-
const { name, arguments: args } = request.params;
|
|
260
|
-
if (name === 'dataset_guide') {
|
|
261
|
-
return datasetGuidePrompt(this.config.datasets, args?.dataset);
|
|
262
|
-
}
|
|
263
|
-
throw new Error(`Unknown prompt: ${name}`);
|
|
12
|
+
const executor = new HypequeryMCPExecutor(config);
|
|
13
|
+
super({
|
|
14
|
+
executor,
|
|
15
|
+
name: config.name,
|
|
16
|
+
version: config.version,
|
|
264
17
|
});
|
|
265
18
|
}
|
|
266
19
|
/**
|
|
267
|
-
* Start the
|
|
20
|
+
* Start with the legacy stdio transport.
|
|
21
|
+
*
|
|
22
|
+
* @deprecated Prefer connect(transport) or startStdioMCPServer(config).
|
|
268
23
|
*/
|
|
269
24
|
async start() {
|
|
270
|
-
const
|
|
271
|
-
await this
|
|
272
|
-
// Log to stderr (stdout is used for MCP protocol)
|
|
273
|
-
console.error('Hypequery MCP Server started');
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* Stop the MCP server
|
|
277
|
-
*/
|
|
278
|
-
async stop() {
|
|
279
|
-
await this.server.close();
|
|
25
|
+
const { connectMCPServerStdio } = await import('./stdio.js');
|
|
26
|
+
await connectMCPServerStdio(this);
|
|
280
27
|
}
|
|
281
28
|
}
|
|
282
29
|
/**
|
|
283
|
-
* Create and start
|
|
30
|
+
* Create and start a backwards-compatible stdio MCP server.
|
|
31
|
+
*
|
|
32
|
+
* @deprecated Prefer createMCPExecutor with createMCPProtocolServer, or
|
|
33
|
+
* startStdioMCPServer for an explicit stdio lifecycle.
|
|
284
34
|
*/
|
|
285
35
|
export async function createMCPServer(config) {
|
|
286
36
|
const server = new HypequeryMCPServer(config);
|
package/dist/stdio.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { MCPServerConfig } from './executor.js';
|
|
2
|
+
import type { HypequeryMCPProtocolServer } from './protocol-server.js';
|
|
3
|
+
import { HypequeryMCPServer } from './server.js';
|
|
4
|
+
/** Connect an existing Hypequery MCP server to the stdio transport. */
|
|
5
|
+
export declare function connectMCPServerStdio(server: HypequeryMCPProtocolServer): Promise<void>;
|
|
6
|
+
/** Create and start the backwards-compatible stdio MCP server. */
|
|
7
|
+
export declare function startStdioMCPServer(config: MCPServerConfig): Promise<HypequeryMCPServer>;
|
|
8
|
+
//# sourceMappingURL=stdio.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,uEAAuE;AACvE,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,0BAA0B,GACjC,OAAO,CAAC,IAAI,CAAC,CAKf;AAED,kEAAkE;AAClE,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,kBAAkB,CAAC,CAI7B"}
|
package/dist/stdio.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
2
|
+
import { HypequeryMCPServer } from './server.js';
|
|
3
|
+
/** Connect an existing Hypequery MCP server to the stdio transport. */
|
|
4
|
+
export async function connectMCPServerStdio(server) {
|
|
5
|
+
await server.connect(new StdioServerTransport());
|
|
6
|
+
// MCP stdio owns stdout, so lifecycle logging must use stderr.
|
|
7
|
+
console.error('Hypequery MCP Server started');
|
|
8
|
+
}
|
|
9
|
+
/** Create and start the backwards-compatible stdio MCP server. */
|
|
10
|
+
export async function startStdioMCPServer(config) {
|
|
11
|
+
const server = new HypequeryMCPServer(config);
|
|
12
|
+
await connectMCPServerStdio(server);
|
|
13
|
+
return server;
|
|
14
|
+
}
|
package/dist/tools/args.d.ts
CHANGED
|
@@ -7,12 +7,12 @@ export declare const queryMetricArgsSchema: z.ZodObject<{
|
|
|
7
7
|
operator: z.ZodEnum<["eq", "neq", "gt", "gte", "lt", "lte", "in", "notIn", "between", "like"]>;
|
|
8
8
|
value: z.ZodEffects<z.ZodAny, any, any>;
|
|
9
9
|
}, "strict", z.ZodTypeAny, {
|
|
10
|
-
operator: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "notIn" | "between" | "like";
|
|
11
10
|
field: string;
|
|
11
|
+
operator: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "notIn" | "between" | "like";
|
|
12
12
|
value?: any;
|
|
13
13
|
}, {
|
|
14
|
-
operator: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "notIn" | "between" | "like";
|
|
15
14
|
field: string;
|
|
15
|
+
operator: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "notIn" | "between" | "like";
|
|
16
16
|
value?: any;
|
|
17
17
|
}>, "many">>;
|
|
18
18
|
grain: z.ZodOptional<z.ZodEnum<["day", "week", "month", "quarter", "year"]>>;
|
|
@@ -32,14 +32,14 @@ export declare const queryMetricArgsSchema: z.ZodObject<{
|
|
|
32
32
|
dataset: z.ZodOptional<z.ZodString>;
|
|
33
33
|
metric: z.ZodOptional<z.ZodString>;
|
|
34
34
|
}, "strict", z.ZodTypeAny, {
|
|
35
|
-
dataset?: string | undefined;
|
|
36
|
-
metric?: string | undefined;
|
|
37
35
|
dimensions?: string[] | undefined;
|
|
38
36
|
filters?: {
|
|
39
|
-
operator: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "notIn" | "between" | "like";
|
|
40
37
|
field: string;
|
|
38
|
+
operator: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "notIn" | "between" | "like";
|
|
41
39
|
value?: any;
|
|
42
40
|
}[] | undefined;
|
|
41
|
+
metric?: string | undefined;
|
|
42
|
+
dataset?: string | undefined;
|
|
43
43
|
grain?: "day" | "week" | "month" | "quarter" | "year" | undefined;
|
|
44
44
|
orderBy?: {
|
|
45
45
|
field: string;
|
|
@@ -48,14 +48,14 @@ export declare const queryMetricArgsSchema: z.ZodObject<{
|
|
|
48
48
|
limit?: number | undefined;
|
|
49
49
|
offset?: number | undefined;
|
|
50
50
|
}, {
|
|
51
|
-
dataset?: string | undefined;
|
|
52
|
-
metric?: string | undefined;
|
|
53
51
|
dimensions?: string[] | undefined;
|
|
54
52
|
filters?: {
|
|
55
|
-
operator: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "notIn" | "between" | "like";
|
|
56
53
|
field: string;
|
|
54
|
+
operator: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "notIn" | "between" | "like";
|
|
57
55
|
value?: any;
|
|
58
56
|
}[] | undefined;
|
|
57
|
+
metric?: string | undefined;
|
|
58
|
+
dataset?: string | undefined;
|
|
59
59
|
grain?: "day" | "week" | "month" | "quarter" | "year" | undefined;
|
|
60
60
|
orderBy?: {
|
|
61
61
|
field: string;
|
|
@@ -71,12 +71,12 @@ export declare const queryDatasetArgsSchema: z.ZodObject<{
|
|
|
71
71
|
operator: z.ZodEnum<["eq", "neq", "gt", "gte", "lt", "lte", "in", "notIn", "between", "like"]>;
|
|
72
72
|
value: z.ZodEffects<z.ZodAny, any, any>;
|
|
73
73
|
}, "strict", z.ZodTypeAny, {
|
|
74
|
-
operator: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "notIn" | "between" | "like";
|
|
75
74
|
field: string;
|
|
75
|
+
operator: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "notIn" | "between" | "like";
|
|
76
76
|
value?: any;
|
|
77
77
|
}, {
|
|
78
|
-
operator: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "notIn" | "between" | "like";
|
|
79
78
|
field: string;
|
|
79
|
+
operator: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "notIn" | "between" | "like";
|
|
80
80
|
value?: any;
|
|
81
81
|
}>, "many">>;
|
|
82
82
|
grain: z.ZodOptional<z.ZodEnum<["day", "week", "month", "quarter", "year"]>>;
|
|
@@ -96,13 +96,14 @@ export declare const queryDatasetArgsSchema: z.ZodObject<{
|
|
|
96
96
|
dataset: z.ZodOptional<z.ZodString>;
|
|
97
97
|
measures: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
98
98
|
}, "strict", z.ZodTypeAny, {
|
|
99
|
-
dataset?: string | undefined;
|
|
100
99
|
dimensions?: string[] | undefined;
|
|
101
100
|
filters?: {
|
|
102
|
-
operator: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "notIn" | "between" | "like";
|
|
103
101
|
field: string;
|
|
102
|
+
operator: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "notIn" | "between" | "like";
|
|
104
103
|
value?: any;
|
|
105
104
|
}[] | undefined;
|
|
105
|
+
measures?: string[] | undefined;
|
|
106
|
+
dataset?: string | undefined;
|
|
106
107
|
grain?: "day" | "week" | "month" | "quarter" | "year" | undefined;
|
|
107
108
|
orderBy?: {
|
|
108
109
|
field: string;
|
|
@@ -110,15 +111,15 @@ export declare const queryDatasetArgsSchema: z.ZodObject<{
|
|
|
110
111
|
}[] | undefined;
|
|
111
112
|
limit?: number | undefined;
|
|
112
113
|
offset?: number | undefined;
|
|
113
|
-
measures?: string[] | undefined;
|
|
114
114
|
}, {
|
|
115
|
-
dataset?: string | undefined;
|
|
116
115
|
dimensions?: string[] | undefined;
|
|
117
116
|
filters?: {
|
|
118
|
-
operator: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "notIn" | "between" | "like";
|
|
119
117
|
field: string;
|
|
118
|
+
operator: "eq" | "neq" | "gt" | "gte" | "lt" | "lte" | "in" | "notIn" | "between" | "like";
|
|
120
119
|
value?: any;
|
|
121
120
|
}[] | undefined;
|
|
121
|
+
measures?: string[] | undefined;
|
|
122
|
+
dataset?: string | undefined;
|
|
122
123
|
grain?: "day" | "week" | "month" | "quarter" | "year" | undefined;
|
|
123
124
|
orderBy?: {
|
|
124
125
|
field: string;
|
|
@@ -126,7 +127,6 @@ export declare const queryDatasetArgsSchema: z.ZodObject<{
|
|
|
126
127
|
}[] | undefined;
|
|
127
128
|
limit?: number | undefined;
|
|
128
129
|
offset?: number | undefined;
|
|
129
|
-
measures?: string[] | undefined;
|
|
130
130
|
}>;
|
|
131
131
|
export declare function parseToolArgs<T>(schema: z.ZodType<T>, toolName: string, args: unknown): T;
|
|
132
132
|
export declare function toMetricFilters(filters?: Array<{
|
package/dist/tools/args.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/tools/args.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAA6B,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/tools/args.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAA6B,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AA+BnF,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGhC,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAGjC,CAAC;AAWH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,CAAC,CASzF;AAED,wBAAgB,eAAe,CAC7B,OAAO,GAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAAM,GAC1F,YAAY,EAAE,CAMhB"}
|