Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .changeset/describe-source-tool.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
'@hyperdx/api': patch
---

feat(mcp): add hyperdx_describe_source tool and slim list_sources to catalog

Add `hyperdx_describe_source` — returns full column schema, map attribute
keys, and sampled low-cardinality values (SeverityText, StatusCode,
ServiceName, etc.) for a single source. Uses existing rollup tables for
performant value sampling.

Slim `hyperdx_list_sources` to a lightweight MongoDB-only catalog (no
ClickHouse queries). Source tools moved to a dedicated `tools/sources/`
module.

All query tool descriptions and prompts updated to reference the two-step
`list_sources → describe_source` discovery workflow.
3 changes: 2 additions & 1 deletion MCP.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ with:

| Tool | Description |
| ----------------------------- | -------------------------------------------------------------------------------------------- |
| `hyperdx_list_sources` | List all data sources and database connections, including column schemas and attribute keys |
| `hyperdx_list_sources` | List all data sources and connections as a lightweight catalog (IDs, names, kinds) |
| `hyperdx_describe_source` | Full column schema, attribute keys, and sampled low-cardinality values for a single source |
| `hyperdx_timeseries` | Plot metrics over time as a line or stacked bar chart |
| `hyperdx_table` | Compute aggregated metrics as a table, single number, or pie chart |
| `hyperdx_search` | Browse individual log, event, or trace rows |
Expand Down
59 changes: 0 additions & 59 deletions packages/api/src/mcp/__tests__/dashboards.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,65 +76,6 @@ describe('MCP Dashboard Tools', () => {
await server.stop();
});

describe('hyperdx_list_sources', () => {
it('should list available sources and connections', async () => {
const result = await callTool(client, 'hyperdx_list_sources');

expect(result.isError).toBeFalsy();
expect(result.content).toHaveLength(1);

const output = JSON.parse(getFirstText(result));
expect(output.sources).toHaveLength(1);
expect(output.sources[0]).toMatchObject({
id: traceSource._id.toString(),
name: 'Traces',
kind: SourceKind.Trace,
});

expect(output.connections).toHaveLength(1);
expect(output.connections[0]).toMatchObject({
id: connection._id.toString(),
name: 'Default',
});

expect(output.usage).toBeDefined();
});

it('should include column schema for sources', async () => {
const result = await callTool(client, 'hyperdx_list_sources');
const output = JSON.parse(getFirstText(result));
const source = output.sources[0];

expect(source.columns).toBeDefined();
expect(Array.isArray(source.columns)).toBe(true);
expect(source.columns.length).toBeGreaterThan(0);
// Each column should have name, type, and jsType
expect(source.columns[0]).toHaveProperty('name');
expect(source.columns[0]).toHaveProperty('type');
expect(source.columns[0]).toHaveProperty('jsType');
});

it('should return empty sources for a team with no sources', async () => {
// Clear everything and re-register with new team
await client.close();
await server.clearDBs();
const result2 = await getLoggedInAgent(server);
const context2: McpContext = {
teamId: result2.team._id.toString(),
userId: result2.user._id.toString(),
};
const client2 = await createTestClient(context2);

const result = await callTool(client2, 'hyperdx_list_sources');
const output = JSON.parse(getFirstText(result));

expect(output.sources).toHaveLength(0);
expect(output.connections).toHaveLength(0);

await client2.close();
});
});

describe('hyperdx_get_dashboard', () => {
it('should list all dashboards when no id provided', async () => {
await new Dashboard({
Expand Down
Loading
Loading