@lightdash-tools/mcp 0.2.5 → 0.3.1

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 CHANGED
@@ -77,7 +77,7 @@ With auth disabled (default), any client can call the endpoint. With `MCP_AUTH_E
77
77
  The server registers the following tools (names prefixed with `lightdash_tools__`):
78
78
 
79
79
  - **Projects**: `list_projects`, `get_project`, `validate_project`, `get_validation_results`
80
- - **Explores**: `list_explores`, `get_explore`, `list_dimensions`, `get_field_lineage`
80
+ - **Explores**: `list_explores`, `get_explore`
81
81
  - **Charts**: `list_charts`, `list_charts_as_code`, `upsert_chart_as_code`
82
82
  - **Dashboards**: `list_dashboards`
83
83
  - **Spaces**: `list_spaces`, `get_space`
@@ -87,20 +87,35 @@ The server registers the following tools (names prefixed with `lightdash_tools__
87
87
  - **Schedulers**: `list_schedulers`
88
88
  - **Tags**: `list_tags`
89
89
  - **Query**: `compile_query`
90
- - **Content**: `search_content`
90
+ - **Content**: `search_content` (v2)
91
+ - **AI Agents**:
92
+ - **Admin**: `list_admin_agents`, `list_admin_agent_threads`, `get_ai_organization_settings`, `update_ai_organization_settings`
93
+ - **Agent Management**: `list_project_agents`, `get_project_agent`, `create_project_agent`, `update_project_agent`, `delete_project_agent`
94
+ - **Conversations**: `list_agent_threads`, `get_agent_thread`, `generate_agent_message`, `continue_agent_thread`
95
+ - **Evaluations**: `list_agent_evaluations`, `get_agent_evaluation`, `create_agent_evaluation`, `update_agent_evaluation`, `append_agent_evaluation_prompts`, `run_agent_evaluation`, `list_agent_evaluation_runs`, `get_agent_evaluation_run_results`, `delete_agent_evaluation`
96
+
97
+ ### CLI Binary
98
+
99
+ If installed globally, you can use the `lightdash-mcp` binary:
100
+
101
+ ```bash
102
+ lightdash-mcp --help
103
+ ```
91
104
 
92
105
  ### CLI Options
93
106
 
94
107
  - `--http` — Run as HTTP server instead of Stdio.
95
108
  - `--safety-mode <mode>` — Filter registered tools by safety mode (`read-only`, `write-idempotent`, `write-destructive`). Tools not allowed in this mode will not be registered, hiding them from AI agents (Static Filtering).
109
+ - `--projects <uuids>` — Comma-separated list of allowed project UUIDs (overrides `LIGHTDASH_ALLOWED_PROJECTS`; empty = all allowed).
110
+ - `--dry-run` — Simulate write operations without executing them (overrides `LIGHTDASH_DRY_RUN`).
96
111
 
97
112
  ## Safety Modes
98
113
 
99
114
  The MCP server implements a hierarchical safety model. You can control which tools are available to AI agents using the `LIGHTDASH_TOOL_SAFETY_MODE` environment variable or the `--safety-mode` CLI option.
100
115
 
101
- - `read-only`: Only allows non-modifying tools (e.g., `list_*`, `get_*`).
116
+ - `read-only` (default): Only allows non-modifying tools (e.g., `list_*`, `get_*`).
102
117
  - `write-idempotent`: Allows read tools and non-destructive writes (e.g., `upsert_chart_as_code`).
103
- - `write-destructive` (default): Allows all tools, including destructive ones (e.g., `delete_member`).
118
+ - `write-destructive`: Allows all tools, including destructive ones (e.g., `delete_member`).
104
119
 
105
120
  ### Enforcement Layers
106
121
 
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Re-exports the shared audit logger from @lightdash-tools/common.
3
+ * The canonical implementation lives in common so the CLI can also use it.
4
+ */
5
+ export { getSessionId, initAuditLog, logAuditEntry } from '@lightdash-tools/common';
6
+ export type { AuditLogEntry, AuditStatus } from '@lightdash-tools/common';
package/dist/audit.js ADDED
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.logAuditEntry = exports.initAuditLog = exports.getSessionId = void 0;
4
+ /**
5
+ * Re-exports the shared audit logger from @lightdash-tools/common.
6
+ * The canonical implementation lives in common so the CLI can also use it.
7
+ */
8
+ var common_1 = require("@lightdash-tools/common");
9
+ Object.defineProperty(exports, "getSessionId", { enumerable: true, get: function () { return common_1.getSessionId; } });
10
+ Object.defineProperty(exports, "initAuditLog", { enumerable: true, get: function () { return common_1.initAuditLog; } });
11
+ Object.defineProperty(exports, "logAuditEntry", { enumerable: true, get: function () { return common_1.logAuditEntry; } });
package/dist/bin.js CHANGED
@@ -44,9 +44,11 @@ const program = new commander_1.Command();
44
44
  program
45
45
  .name('lightdash-mcp')
46
46
  .description('MCP server for Lightdash AI')
47
- .version('0.2.5')
47
+ .version('0.3.1')
48
48
  .option('--http', 'Run as HTTP server instead of Stdio')
49
49
  .option('--safety-mode <mode>', 'Filter registered tools by safety mode (read-only, write-idempotent, write-destructive)')
50
+ .option('--projects <uuids>', 'Comma-separated list of allowed project UUIDs (overrides LIGHTDASH_ALLOWED_PROJECTS; empty = all allowed)')
51
+ .option('--dry-run', 'Simulate write operations without executing them (overrides LIGHTDASH_DRY_RUN)')
50
52
  .action((options) => {
51
53
  if (options.safetyMode) {
52
54
  if (Object.values(common_1.SafetyMode).includes(options.safetyMode)) {
@@ -57,6 +59,16 @@ program
57
59
  process.exit(1);
58
60
  }
59
61
  }
62
+ if (options.projects) {
63
+ const uuids = options.projects
64
+ .split(',')
65
+ .map((s) => s.trim())
66
+ .filter(Boolean);
67
+ (0, config_js_1.setStaticAllowedProjectUuids)(uuids);
68
+ }
69
+ if (options.dryRun) {
70
+ (0, config_js_1.setDryRunMode)(true);
71
+ }
60
72
  if (options.http) {
61
73
  void Promise.resolve().then(() => __importStar(require('./http.js')));
62
74
  }
package/dist/config.d.ts CHANGED
@@ -17,6 +17,29 @@ export declare function getStaticSafetyMode(): SafetyMode | undefined;
17
17
  * Sets the static safety mode (from CLI).
18
18
  */
19
19
  export declare function setStaticSafetyMode(mode: SafetyMode): void;
20
+ /**
21
+ * Returns the effective project UUID allowlist.
22
+ * CLI-provided values override the environment variable.
23
+ * An empty array means all projects are allowed.
24
+ */
25
+ export declare function getAllowedProjectUuids(): string[];
26
+ /**
27
+ * Sets the project UUID allowlist from the CLI (overrides LIGHTDASH_ALLOWED_PROJECTS).
28
+ */
29
+ export declare function setStaticAllowedProjectUuids(uuids: string[]): void;
30
+ /**
31
+ * Returns true when dry-run mode is active.
32
+ * CLI flag overrides the LIGHTDASH_DRY_RUN environment variable.
33
+ */
34
+ export declare function isDryRunMode(): boolean;
35
+ /**
36
+ * Enables or disables dry-run mode (from CLI).
37
+ */
38
+ export declare function setDryRunMode(enabled: boolean): void;
39
+ /**
40
+ * Returns the audit log file path from LIGHTDASH_AUDIT_LOG, or undefined to use stderr.
41
+ */
42
+ export declare function getAuditLogPath(): string | undefined;
20
43
  /**
21
44
  * Builds a LightdashClient from environment variables (and optional overrides).
22
45
  * Throws if LIGHTDASH_URL or LIGHTDASH_API_KEY are missing.
package/dist/config.js CHANGED
@@ -7,10 +7,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.getSafetyMode = getSafetyMode;
8
8
  exports.getStaticSafetyMode = getStaticSafetyMode;
9
9
  exports.setStaticSafetyMode = setStaticSafetyMode;
10
+ exports.getAllowedProjectUuids = getAllowedProjectUuids;
11
+ exports.setStaticAllowedProjectUuids = setStaticAllowedProjectUuids;
12
+ exports.isDryRunMode = isDryRunMode;
13
+ exports.setDryRunMode = setDryRunMode;
14
+ exports.getAuditLogPath = getAuditLogPath;
10
15
  exports.getClient = getClient;
11
16
  const client_1 = require("@lightdash-tools/client");
12
17
  const common_1 = require("@lightdash-tools/common");
13
18
  let globalStaticSafetyMode;
19
+ let globalStaticAllowedProjectUuids;
20
+ let globalDryRunMode;
14
21
  /**
15
22
  * Gets the safety mode for dynamic enforcement.
16
23
  */
@@ -29,6 +36,42 @@ function getStaticSafetyMode() {
29
36
  function setStaticSafetyMode(mode) {
30
37
  globalStaticSafetyMode = mode;
31
38
  }
39
+ /**
40
+ * Returns the effective project UUID allowlist.
41
+ * CLI-provided values override the environment variable.
42
+ * An empty array means all projects are allowed.
43
+ */
44
+ function getAllowedProjectUuids() {
45
+ return globalStaticAllowedProjectUuids !== null && globalStaticAllowedProjectUuids !== void 0 ? globalStaticAllowedProjectUuids : (0, common_1.getAllowedProjectUuidsFromEnv)();
46
+ }
47
+ /**
48
+ * Sets the project UUID allowlist from the CLI (overrides LIGHTDASH_ALLOWED_PROJECTS).
49
+ */
50
+ function setStaticAllowedProjectUuids(uuids) {
51
+ globalStaticAllowedProjectUuids = uuids;
52
+ }
53
+ /**
54
+ * Returns true when dry-run mode is active.
55
+ * CLI flag overrides the LIGHTDASH_DRY_RUN environment variable.
56
+ */
57
+ function isDryRunMode() {
58
+ if (globalDryRunMode !== undefined)
59
+ return globalDryRunMode;
60
+ const v = process.env.LIGHTDASH_DRY_RUN;
61
+ return v === '1' || v === 'true' || v === 'yes';
62
+ }
63
+ /**
64
+ * Enables or disables dry-run mode (from CLI).
65
+ */
66
+ function setDryRunMode(enabled) {
67
+ globalDryRunMode = enabled;
68
+ }
69
+ /**
70
+ * Returns the audit log file path from LIGHTDASH_AUDIT_LOG, or undefined to use stderr.
71
+ */
72
+ function getAuditLogPath() {
73
+ return process.env.LIGHTDASH_AUDIT_LOG || undefined;
74
+ }
32
75
  /**
33
76
  * Builds a LightdashClient from environment variables (and optional overrides).
34
77
  * Throws if LIGHTDASH_URL or LIGHTDASH_API_KEY are missing.
package/dist/http.js CHANGED
@@ -19,6 +19,7 @@ const node_crypto_1 = require("node:crypto");
19
19
  const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
20
20
  const streamableHttp_js_1 = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
21
21
  const config_js_1 = require("./config.js");
22
+ const audit_js_1 = require("./audit.js");
22
23
  const index_js_1 = require("./tools/index.js");
23
24
  const MCP_PATH = '/mcp';
24
25
  const PORT = Number((_a = process.env.MCP_HTTP_PORT) !== null && _a !== void 0 ? _a : '3100');
@@ -155,6 +156,7 @@ function handleRequest(req, res) {
155
156
  });
156
157
  }
157
158
  function main() {
159
+ (0, audit_js_1.initAuditLog)((0, config_js_1.getAuditLogPath)());
158
160
  const server = (0, node_http_1.createServer)((req, res) => {
159
161
  handleRequest(req, res).catch((err) => {
160
162
  console.error('MCP HTTP handler error:', err);
package/dist/index.js CHANGED
@@ -15,16 +15,18 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
16
  const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
17
17
  const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
18
- const config_1 = require("./config");
19
- const tools_1 = require("./tools");
18
+ const config_js_1 = require("./config.js");
19
+ const audit_js_1 = require("./audit.js");
20
+ const index_js_1 = require("./tools/index.js");
20
21
  function main() {
21
22
  return __awaiter(this, void 0, void 0, function* () {
22
- const client = (0, config_1.getClient)();
23
+ (0, audit_js_1.initAuditLog)((0, config_js_1.getAuditLogPath)());
24
+ const client = (0, config_js_1.getClient)();
23
25
  const server = new mcp_js_1.McpServer({
24
26
  name: 'lightdash-mcp',
25
27
  version: '1.0.0',
26
28
  });
27
- (0, tools_1.registerTools)(server, client);
29
+ (0, index_js_1.registerTools)(server, client);
28
30
  const transport = new stdio_js_1.StdioServerTransport();
29
31
  yield server.connect(transport);
30
32
  console.error('Lightdash MCP server running on stdio');
@@ -0,0 +1,6 @@
1
+ /**
2
+ * MCP tools: AI agents (admin + project-scoped), threads, and evaluations.
3
+ */
4
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
+ import type { LightdashClient } from '@lightdash-tools/client';
6
+ export declare function registerAiAgentTools(server: McpServer, client: LightdashClient): void;
@@ -0,0 +1,388 @@
1
+ "use strict";
2
+ /**
3
+ * MCP tools: AI agents (admin + project-scoped), threads, and evaluations.
4
+ */
5
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7
+ return new (P || (P = Promise))(function (resolve, reject) {
8
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
12
+ });
13
+ };
14
+ var __rest = (this && this.__rest) || function (s, e) {
15
+ var t = {};
16
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
17
+ t[p] = s[p];
18
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
19
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
20
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
21
+ t[p[i]] = s[p[i]];
22
+ }
23
+ return t;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.registerAiAgentTools = registerAiAgentTools;
27
+ const zod_1 = require("zod");
28
+ const shared_js_1 = require("./shared.js");
29
+ function registerAiAgentTools(server, client) {
30
+ // ─── Admin: agents ───────────────────────────────────────────────────────────
31
+ (0, shared_js_1.registerToolSafe)(server, 'list_admin_agents', {
32
+ title: 'List AI agents (admin)',
33
+ description: 'List all AI agents across the organization (admin view)',
34
+ inputSchema: {},
35
+ annotations: shared_js_1.READ_ONLY_DEFAULT,
36
+ }, (0, shared_js_1.wrapTool)(client, (c) => () => __awaiter(this, void 0, void 0, function* () {
37
+ const result = yield c.v1.aiAgents.listAdminAgents();
38
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
39
+ })));
40
+ // ─── Admin: threads ──────────────────────────────────────────────────────────
41
+ (0, shared_js_1.registerToolSafe)(server, 'list_admin_agent_threads', {
42
+ title: 'List AI agent threads (admin)',
43
+ description: 'List AI agent conversation threads across the organization with optional filters',
44
+ inputSchema: {
45
+ page: zod_1.z.number().optional().describe('Page number (1-based)'),
46
+ pageSize: zod_1.z.number().optional().describe('Number of results per page'),
47
+ agentUuids: zod_1.z.array(zod_1.z.string()).optional().describe('Filter by agent UUIDs'),
48
+ projectUuids: zod_1.z.array(zod_1.z.string()).optional().describe('Filter by project UUIDs'),
49
+ humanScore: zod_1.z
50
+ .number()
51
+ .optional()
52
+ .describe('Filter by human score: -1 (negative), 0 (neutral), 1 (positive)'),
53
+ dateFrom: zod_1.z.string().optional().describe('Start date filter (YYYY-MM-DD)'),
54
+ dateTo: zod_1.z.string().optional().describe('End date filter (YYYY-MM-DD)'),
55
+ sortField: zod_1.z.enum(['createdAt', 'title']).optional().describe('Sort field'),
56
+ sortDirection: zod_1.z.enum(['asc', 'desc']).optional().describe('Sort direction'),
57
+ },
58
+ annotations: shared_js_1.READ_ONLY_DEFAULT,
59
+ }, (0, shared_js_1.wrapTool)(client, (c) => (params) => __awaiter(this, void 0, void 0, function* () {
60
+ const result = yield c.v1.aiAgents.getAdminThreads(params);
61
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
62
+ })));
63
+ // ─── Admin: settings ─────────────────────────────────────────────────────────
64
+ (0, shared_js_1.registerToolSafe)(server, 'get_ai_organization_settings', {
65
+ title: 'Get AI organization settings',
66
+ description: 'Get the AI settings for the current organization (admin)',
67
+ inputSchema: {},
68
+ annotations: shared_js_1.READ_ONLY_DEFAULT,
69
+ }, (0, shared_js_1.wrapTool)(client, (c) => () => __awaiter(this, void 0, void 0, function* () {
70
+ const result = yield c.v1.aiAgents.getAiOrganizationSettings();
71
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
72
+ })));
73
+ (0, shared_js_1.registerToolSafe)(server, 'update_ai_organization_settings', {
74
+ title: 'Update AI organization settings',
75
+ description: 'Update the AI settings for the current organization (admin)',
76
+ inputSchema: {
77
+ aiAgentsVisible: zod_1.z
78
+ .boolean()
79
+ .optional()
80
+ .describe('Whether AI agents feature is visible to users'),
81
+ },
82
+ annotations: shared_js_1.WRITE_IDEMPOTENT,
83
+ }, (0, shared_js_1.wrapTool)(client, (c) => (params) => __awaiter(this, void 0, void 0, function* () {
84
+ const result = yield c.v1.aiAgents.updateAiOrganizationSettings(params);
85
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
86
+ })));
87
+ // ─── Project-scoped: agent CRUD ──────────────────────────────────────────────
88
+ (0, shared_js_1.registerToolSafe)(server, 'list_project_agents', {
89
+ title: 'List agents in a project',
90
+ description: 'List all AI agents configured for a specific project',
91
+ inputSchema: {
92
+ projectUuid: zod_1.z.string().describe('Project UUID'),
93
+ },
94
+ annotations: shared_js_1.READ_ONLY_DEFAULT,
95
+ }, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ projectUuid }) {
96
+ const result = yield c.v1.aiAgents.listAgents(projectUuid);
97
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
98
+ })));
99
+ (0, shared_js_1.registerToolSafe)(server, 'get_project_agent', {
100
+ title: 'Get agent',
101
+ description: 'Get details of a specific AI agent in a project',
102
+ inputSchema: {
103
+ projectUuid: zod_1.z.string().describe('Project UUID'),
104
+ agentUuid: zod_1.z.string().describe('Agent UUID'),
105
+ },
106
+ annotations: shared_js_1.READ_ONLY_DEFAULT,
107
+ }, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ projectUuid, agentUuid }) {
108
+ const result = yield c.v1.aiAgents.getAgent(projectUuid, agentUuid);
109
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
110
+ })));
111
+ (0, shared_js_1.registerToolSafe)(server, 'create_project_agent', {
112
+ title: 'Create agent',
113
+ description: 'Create a new AI agent in a project',
114
+ inputSchema: {
115
+ projectUuid: zod_1.z.string().describe('Project UUID'),
116
+ name: zod_1.z.string().describe('Agent name'),
117
+ description: zod_1.z.string().optional().describe('Agent description'),
118
+ instruction: zod_1.z.string().optional().describe('System instruction for the agent'),
119
+ },
120
+ annotations: shared_js_1.WRITE_IDEMPOTENT,
121
+ }, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ projectUuid, name, description, instruction, }) {
122
+ const body = Object.assign(Object.assign({ name,
123
+ projectUuid }, (description != null ? { description } : {})), (instruction != null ? { instruction } : {}));
124
+ const result = yield c.v1.aiAgents.createAgent(projectUuid, body);
125
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
126
+ })));
127
+ (0, shared_js_1.registerToolSafe)(server, 'update_project_agent', {
128
+ title: 'Update agent',
129
+ description: 'Update an existing AI agent',
130
+ inputSchema: {
131
+ projectUuid: zod_1.z.string().describe('Project UUID'),
132
+ agentUuid: zod_1.z.string().describe('Agent UUID'),
133
+ name: zod_1.z.string().optional().describe('New name'),
134
+ description: zod_1.z.string().optional().describe('New description'),
135
+ instruction: zod_1.z.string().optional().describe('New system instruction'),
136
+ },
137
+ annotations: shared_js_1.WRITE_IDEMPOTENT,
138
+ }, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, void 0, void 0, function* () {
139
+ var { projectUuid, agentUuid } = _a, body = __rest(_a, ["projectUuid", "agentUuid"]);
140
+ const result = yield c.v1.aiAgents.updateAgent(projectUuid, agentUuid, body);
141
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
142
+ })));
143
+ (0, shared_js_1.registerToolSafe)(server, 'delete_project_agent', {
144
+ title: 'Delete agent',
145
+ description: 'Delete an AI agent from a project',
146
+ inputSchema: {
147
+ projectUuid: zod_1.z.string().describe('Project UUID'),
148
+ agentUuid: zod_1.z.string().describe('Agent UUID'),
149
+ },
150
+ annotations: shared_js_1.WRITE_DESTRUCTIVE,
151
+ }, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ projectUuid, agentUuid }) {
152
+ yield c.v1.aiAgents.deleteAgent(projectUuid, agentUuid);
153
+ return {
154
+ content: [{ type: 'text', text: `Agent ${agentUuid} deleted successfully` }],
155
+ };
156
+ })));
157
+ // ─── Project-scoped: threads ─────────────────────────────────────────────────
158
+ (0, shared_js_1.registerToolSafe)(server, 'list_agent_threads', {
159
+ title: 'List agent threads',
160
+ description: 'List all conversation threads for an agent',
161
+ inputSchema: {
162
+ projectUuid: zod_1.z.string().describe('Project UUID'),
163
+ agentUuid: zod_1.z.string().describe('Agent UUID'),
164
+ },
165
+ annotations: shared_js_1.READ_ONLY_DEFAULT,
166
+ }, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ projectUuid, agentUuid }) {
167
+ const result = yield c.v1.aiAgents.listAgentThreads(projectUuid, agentUuid);
168
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
169
+ })));
170
+ (0, shared_js_1.registerToolSafe)(server, 'get_agent_thread', {
171
+ title: 'Get agent thread',
172
+ description: 'Get a conversation thread with all its messages',
173
+ inputSchema: {
174
+ projectUuid: zod_1.z.string().describe('Project UUID'),
175
+ agentUuid: zod_1.z.string().describe('Agent UUID'),
176
+ threadUuid: zod_1.z.string().describe('Thread UUID'),
177
+ },
178
+ annotations: shared_js_1.READ_ONLY_DEFAULT,
179
+ }, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ projectUuid, agentUuid, threadUuid, }) {
180
+ const result = yield c.v1.aiAgents.getAgentThread(projectUuid, agentUuid, threadUuid);
181
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
182
+ })));
183
+ (0, shared_js_1.registerToolSafe)(server, 'generate_agent_message', {
184
+ title: 'Generate agent message',
185
+ description: 'Start a new conversation thread and generate the first agent response for a given prompt',
186
+ inputSchema: {
187
+ projectUuid: zod_1.z.string().describe('Project UUID'),
188
+ agentUuid: zod_1.z.string().describe('Agent UUID'),
189
+ prompt: zod_1.z.string().describe('User prompt to send to the agent'),
190
+ },
191
+ annotations: shared_js_1.WRITE_IDEMPOTENT,
192
+ }, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ projectUuid, agentUuid, prompt, }) {
193
+ const thread = yield c.v1.aiAgents.createAgentThread(projectUuid, agentUuid);
194
+ const result = yield c.v1.aiAgents.generateAgentThreadResponse(projectUuid, agentUuid, thread.uuid, { prompt });
195
+ return {
196
+ content: [
197
+ {
198
+ type: 'text',
199
+ text: JSON.stringify(Object.assign({ threadUuid: thread.uuid }, result), null, 2),
200
+ },
201
+ ],
202
+ };
203
+ })));
204
+ (0, shared_js_1.registerToolSafe)(server, 'continue_agent_thread', {
205
+ title: 'Continue agent thread',
206
+ description: 'Continue an existing conversation thread with a new prompt',
207
+ inputSchema: {
208
+ projectUuid: zod_1.z.string().describe('Project UUID'),
209
+ agentUuid: zod_1.z.string().describe('Agent UUID'),
210
+ threadUuid: zod_1.z.string().describe('Thread UUID to continue'),
211
+ prompt: zod_1.z.string().describe('Follow-up prompt'),
212
+ },
213
+ annotations: shared_js_1.WRITE_IDEMPOTENT,
214
+ }, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ projectUuid, agentUuid, threadUuid, prompt, }) {
215
+ const result = yield c.v1.aiAgents.generateAgentThreadResponse(projectUuid, agentUuid, threadUuid, { prompt });
216
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
217
+ })));
218
+ // ─── Project-scoped: evaluations ─────────────────────────────────────────────
219
+ (0, shared_js_1.registerToolSafe)(server, 'list_agent_evaluations', {
220
+ title: 'List agent evaluations',
221
+ description: 'List all evaluations for an agent',
222
+ inputSchema: {
223
+ projectUuid: zod_1.z.string().describe('Project UUID'),
224
+ agentUuid: zod_1.z.string().describe('Agent UUID'),
225
+ },
226
+ annotations: shared_js_1.READ_ONLY_DEFAULT,
227
+ }, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ projectUuid, agentUuid }) {
228
+ const result = yield c.v1.aiAgents.listEvaluations(projectUuid, agentUuid);
229
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
230
+ })));
231
+ (0, shared_js_1.registerToolSafe)(server, 'get_agent_evaluation', {
232
+ title: 'Get agent evaluation',
233
+ description: 'Get a full evaluation including its test prompts',
234
+ inputSchema: {
235
+ projectUuid: zod_1.z.string().describe('Project UUID'),
236
+ agentUuid: zod_1.z.string().describe('Agent UUID'),
237
+ evalUuid: zod_1.z.string().describe('Evaluation UUID'),
238
+ },
239
+ annotations: shared_js_1.READ_ONLY_DEFAULT,
240
+ }, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ projectUuid, agentUuid, evalUuid, }) {
241
+ const result = yield c.v1.aiAgents.getEvaluation(projectUuid, agentUuid, evalUuid);
242
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
243
+ })));
244
+ (0, shared_js_1.registerToolSafe)(server, 'create_agent_evaluation', {
245
+ title: 'Create agent evaluation',
246
+ description: 'Create a new evaluation test suite for an agent with a title and optional prompts',
247
+ inputSchema: {
248
+ projectUuid: zod_1.z.string().describe('Project UUID'),
249
+ agentUuid: zod_1.z.string().describe('Agent UUID'),
250
+ title: zod_1.z.string().describe('Evaluation title'),
251
+ description: zod_1.z.string().optional().describe('Evaluation description'),
252
+ prompts: zod_1.z
253
+ .array(zod_1.z.union([
254
+ zod_1.z.object({
255
+ prompt: zod_1.z.string().describe('Test prompt text'),
256
+ expectedResponse: zod_1.z.string().nullable().describe('Expected response (optional)'),
257
+ }),
258
+ zod_1.z.object({
259
+ threadUuid: zod_1.z.string().describe('Existing thread UUID'),
260
+ promptUuid: zod_1.z.string().describe('Existing prompt UUID within the thread'),
261
+ expectedResponse: zod_1.z.string().nullable().describe('Expected response (optional)'),
262
+ }),
263
+ ]))
264
+ .optional()
265
+ .describe('Test prompts for the evaluation'),
266
+ },
267
+ annotations: shared_js_1.WRITE_IDEMPOTENT,
268
+ }, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ projectUuid, agentUuid, title, description, prompts, }) {
269
+ const body = Object.assign({ title, prompts: prompts !== null && prompts !== void 0 ? prompts : [] }, (description != null ? { description } : {}));
270
+ const result = yield c.v1.aiAgents.createEvaluation(projectUuid, agentUuid, body);
271
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
272
+ })));
273
+ (0, shared_js_1.registerToolSafe)(server, 'update_agent_evaluation', {
274
+ title: 'Update agent evaluation',
275
+ description: 'Update an evaluation title, description, or replace its prompts',
276
+ inputSchema: {
277
+ projectUuid: zod_1.z.string().describe('Project UUID'),
278
+ agentUuid: zod_1.z.string().describe('Agent UUID'),
279
+ evalUuid: zod_1.z.string().describe('Evaluation UUID'),
280
+ title: zod_1.z.string().optional().describe('New title'),
281
+ description: zod_1.z.string().optional().describe('New description'),
282
+ prompts: zod_1.z
283
+ .array(zod_1.z.union([
284
+ zod_1.z.object({
285
+ prompt: zod_1.z.string().describe('Test prompt text'),
286
+ expectedResponse: zod_1.z.string().nullable().describe('Expected response (optional)'),
287
+ }),
288
+ zod_1.z.object({
289
+ threadUuid: zod_1.z.string().describe('Existing thread UUID'),
290
+ promptUuid: zod_1.z.string().describe('Existing prompt UUID within the thread'),
291
+ expectedResponse: zod_1.z.string().nullable().describe('Expected response (optional)'),
292
+ }),
293
+ ]))
294
+ .optional()
295
+ .describe('Replacement prompt list (omit to leave unchanged)'),
296
+ },
297
+ annotations: shared_js_1.WRITE_IDEMPOTENT,
298
+ }, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, void 0, void 0, function* () {
299
+ var { projectUuid, agentUuid, evalUuid } = _a, body = __rest(_a, ["projectUuid", "agentUuid", "evalUuid"]);
300
+ const result = yield c.v1.aiAgents.updateEvaluation(projectUuid, agentUuid, evalUuid, body);
301
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
302
+ })));
303
+ (0, shared_js_1.registerToolSafe)(server, 'append_agent_evaluation_prompts', {
304
+ title: 'Append evaluation prompts',
305
+ description: 'Append additional prompts to an existing evaluation without replacing existing ones',
306
+ inputSchema: {
307
+ projectUuid: zod_1.z.string().describe('Project UUID'),
308
+ agentUuid: zod_1.z.string().describe('Agent UUID'),
309
+ evalUuid: zod_1.z.string().describe('Evaluation UUID'),
310
+ prompts: zod_1.z
311
+ .array(zod_1.z.union([
312
+ zod_1.z.object({
313
+ prompt: zod_1.z.string().describe('Test prompt text'),
314
+ expectedResponse: zod_1.z.string().nullable().describe('Expected response (optional)'),
315
+ }),
316
+ zod_1.z.object({
317
+ threadUuid: zod_1.z.string().describe('Existing thread UUID'),
318
+ promptUuid: zod_1.z.string().describe('Existing prompt UUID within the thread'),
319
+ expectedResponse: zod_1.z.string().nullable().describe('Expected response (optional)'),
320
+ }),
321
+ ]))
322
+ .describe('Prompts to append'),
323
+ },
324
+ annotations: shared_js_1.WRITE_IDEMPOTENT,
325
+ }, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ projectUuid, agentUuid, evalUuid, prompts, }) {
326
+ yield c.v1.aiAgents.appendToEvaluation(projectUuid, agentUuid, evalUuid, { prompts });
327
+ return {
328
+ content: [
329
+ { type: 'text', text: `Prompts appended to evaluation ${evalUuid} successfully` },
330
+ ],
331
+ };
332
+ })));
333
+ (0, shared_js_1.registerToolSafe)(server, 'run_agent_evaluation', {
334
+ title: 'Run agent evaluation',
335
+ description: 'Trigger a new evaluation run for an agent. Returns the run UUID and status.',
336
+ inputSchema: {
337
+ projectUuid: zod_1.z.string().describe('Project UUID'),
338
+ agentUuid: zod_1.z.string().describe('Agent UUID'),
339
+ evalUuid: zod_1.z.string().describe('Evaluation UUID to run'),
340
+ },
341
+ annotations: shared_js_1.WRITE_IDEMPOTENT,
342
+ }, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ projectUuid, agentUuid, evalUuid, }) {
343
+ const result = yield c.v1.aiAgents.runEvaluation(projectUuid, agentUuid, evalUuid);
344
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
345
+ })));
346
+ (0, shared_js_1.registerToolSafe)(server, 'list_agent_evaluation_runs', {
347
+ title: 'List evaluation runs',
348
+ description: 'List all runs for an evaluation with their status and pass/fail counts',
349
+ inputSchema: {
350
+ projectUuid: zod_1.z.string().describe('Project UUID'),
351
+ agentUuid: zod_1.z.string().describe('Agent UUID'),
352
+ evalUuid: zod_1.z.string().describe('Evaluation UUID'),
353
+ },
354
+ annotations: shared_js_1.READ_ONLY_DEFAULT,
355
+ }, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ projectUuid, agentUuid, evalUuid, }) {
356
+ const result = yield c.v1.aiAgents.listEvaluationRuns(projectUuid, agentUuid, evalUuid);
357
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
358
+ })));
359
+ (0, shared_js_1.registerToolSafe)(server, 'get_agent_evaluation_run_results', {
360
+ title: 'Get evaluation run results',
361
+ description: 'Get detailed per-prompt results for a specific evaluation run, including pass/fail and assessments',
362
+ inputSchema: {
363
+ projectUuid: zod_1.z.string().describe('Project UUID'),
364
+ agentUuid: zod_1.z.string().describe('Agent UUID'),
365
+ evalUuid: zod_1.z.string().describe('Evaluation UUID'),
366
+ runUuid: zod_1.z.string().describe('Run UUID'),
367
+ },
368
+ annotations: shared_js_1.READ_ONLY_DEFAULT,
369
+ }, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ projectUuid, agentUuid, evalUuid, runUuid, }) {
370
+ const result = yield c.v1.aiAgents.getEvaluationRunResults(projectUuid, agentUuid, evalUuid, runUuid);
371
+ return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
372
+ })));
373
+ (0, shared_js_1.registerToolSafe)(server, 'delete_agent_evaluation', {
374
+ title: 'Delete agent evaluation',
375
+ description: 'Delete an evaluation and all its runs',
376
+ inputSchema: {
377
+ projectUuid: zod_1.z.string().describe('Project UUID'),
378
+ agentUuid: zod_1.z.string().describe('Agent UUID'),
379
+ evalUuid: zod_1.z.string().describe('Evaluation UUID'),
380
+ },
381
+ annotations: shared_js_1.WRITE_DESTRUCTIVE,
382
+ }, (0, shared_js_1.wrapTool)(client, (c) => (_a) => __awaiter(this, [_a], void 0, function* ({ projectUuid, agentUuid, evalUuid, }) {
383
+ yield c.v1.aiAgents.deleteEvaluation(projectUuid, agentUuid, evalUuid);
384
+ return {
385
+ content: [{ type: 'text', text: `Evaluation ${evalUuid} deleted successfully` }],
386
+ };
387
+ })));
388
+ }
@@ -16,6 +16,7 @@ const metrics_js_1 = require("./metrics.js");
16
16
  const schedulers_js_1 = require("./schedulers.js");
17
17
  const tags_js_1 = require("./tags.js");
18
18
  const content_js_1 = require("./content.js");
19
+ const ai_agents_js_1 = require("./ai-agents.js");
19
20
  function registerTools(server, client) {
20
21
  (0, projects_js_1.registerProjectTools)(server, client);
21
22
  (0, charts_js_1.registerChartTools)(server, client);
@@ -29,4 +30,5 @@ function registerTools(server, client) {
29
30
  (0, schedulers_js_1.registerSchedulersTools)(server, client);
30
31
  (0, tags_js_1.registerTagsTools)(server, client);
31
32
  (0, content_js_1.registerContentTools)(server, client);
33
+ (0, ai_agents_js_1.registerAiAgentTools)(server, client);
32
34
  }