@trylighthouse/mcp-server 0.1.0 → 0.1.2
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/build/index.js +418 -35
- package/package.json +1 -1
package/build/index.js
CHANGED
|
@@ -126,13 +126,11 @@ server.registerTool("lighthouse_crm_get_attribute", {
|
|
|
126
126
|
description: "Get a single custom field definition by its field_permalink.",
|
|
127
127
|
inputSchema: {
|
|
128
128
|
field_permalink: z.string().describe("Field permalink (unique key) of the attribute"),
|
|
129
|
-
entity_type: z.enum(["company", "person", "deal"]).
|
|
129
|
+
entity_type: z.enum(["company", "person", "deal", "task"]).describe("Record type (required)"),
|
|
130
130
|
},
|
|
131
131
|
}, async (params) => {
|
|
132
132
|
try {
|
|
133
|
-
const res = await api.get(`/attributes/${params.field_permalink}
|
|
134
|
-
entity_type: params.entity_type,
|
|
135
|
-
});
|
|
133
|
+
const res = await api.get(`/attributes/${params.entity_type}/${params.field_permalink}`);
|
|
136
134
|
return text(res);
|
|
137
135
|
}
|
|
138
136
|
catch (e) {
|
|
@@ -142,15 +140,16 @@ server.registerTool("lighthouse_crm_get_attribute", {
|
|
|
142
140
|
server.registerTool("lighthouse_crm_create_attribute", {
|
|
143
141
|
title: "Create CRM Attribute",
|
|
144
142
|
description: "Create a new custom field in your CRM workspace. " +
|
|
145
|
-
"
|
|
143
|
+
"Types: text, number, currency, percentage, date, datetimez, select, multi_select, status, checkbox, url, email, phone, rating, record, multi_record, user, multi_user.",
|
|
146
144
|
inputSchema: {
|
|
147
|
-
|
|
148
|
-
entity_type: z.enum(["company", "person", "deal"]).describe("Record type this field belongs to"),
|
|
149
|
-
data_type: z.string().describe("Field type (
|
|
145
|
+
label: z.string().describe("Display label for the field"),
|
|
146
|
+
entity_type: z.enum(["company", "person", "deal", "task"]).describe("Record type this field belongs to"),
|
|
147
|
+
data_type: z.string().describe("Field type (text, number, currency, percentage, date, datetimez, select, multi_select, status, checkbox, url, email, phone, rating, record, multi_record, user, multi_user)"),
|
|
148
|
+
record_type: z.enum(["company", "person", "deal", "task"]).optional().describe("For record/multi_record fields: which record type to link to"),
|
|
150
149
|
options: z
|
|
151
150
|
.array(z.record(z.unknown()))
|
|
152
151
|
.optional()
|
|
153
|
-
.describe("For select/multi_select fields: array of {value, label} option objects"),
|
|
152
|
+
.describe("For select/multi_select/status fields: array of {value, label} option objects"),
|
|
154
153
|
},
|
|
155
154
|
}, async (params) => {
|
|
156
155
|
try {
|
|
@@ -163,16 +162,47 @@ server.registerTool("lighthouse_crm_create_attribute", {
|
|
|
163
162
|
});
|
|
164
163
|
server.registerTool("lighthouse_crm_update_attribute", {
|
|
165
164
|
title: "Update CRM Attribute",
|
|
166
|
-
description: "Update a custom field's
|
|
165
|
+
description: "Update a custom field's label or configuration.",
|
|
167
166
|
inputSchema: {
|
|
168
167
|
field_permalink: z.string().describe("Field permalink of the attribute to update"),
|
|
169
|
-
entity_type: z.enum(["company", "person", "deal"]).
|
|
170
|
-
|
|
168
|
+
entity_type: z.enum(["company", "person", "deal", "task"]).describe("Record type (required)"),
|
|
169
|
+
label: z.string().optional().describe("New display label"),
|
|
171
170
|
},
|
|
172
171
|
}, async (params) => {
|
|
173
172
|
try {
|
|
174
|
-
const { field_permalink, ...body } = params;
|
|
175
|
-
const res = await api.patch(`/attributes/${field_permalink}`, body);
|
|
173
|
+
const { field_permalink, entity_type, ...body } = params;
|
|
174
|
+
const res = await api.patch(`/attributes/${entity_type}/${field_permalink}`, body);
|
|
175
|
+
return text(res);
|
|
176
|
+
}
|
|
177
|
+
catch (e) {
|
|
178
|
+
return err(`Failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
server.registerTool("lighthouse_crm_delete_attribute", {
|
|
182
|
+
title: "Delete CRM Attribute",
|
|
183
|
+
description: "Delete (archive) a custom field. Only custom fields can be deleted, not system fields.",
|
|
184
|
+
inputSchema: {
|
|
185
|
+
field_permalink: z.string().describe("Field permalink of the attribute to delete"),
|
|
186
|
+
entity_type: z.enum(["company", "person", "deal", "task"]).describe("Record type (required)"),
|
|
187
|
+
},
|
|
188
|
+
}, async (params) => {
|
|
189
|
+
try {
|
|
190
|
+
const res = await api.delete(`/attributes/${params.entity_type}/${params.field_permalink}`);
|
|
191
|
+
return text(res);
|
|
192
|
+
}
|
|
193
|
+
catch (e) {
|
|
194
|
+
return err(`Failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
server.registerTool("lighthouse_crm_get_color_palette", {
|
|
198
|
+
title: "Get Color Palette",
|
|
199
|
+
description: "Get the available color palette for select/multi_select/status field options. " +
|
|
200
|
+
"Returns an array of {hex_code, label} objects. " +
|
|
201
|
+
"Use this to discover valid hex color codes when creating or updating select options.",
|
|
202
|
+
inputSchema: {},
|
|
203
|
+
}, async () => {
|
|
204
|
+
try {
|
|
205
|
+
const res = await api.get("/attributes/colors");
|
|
176
206
|
return text(res);
|
|
177
207
|
}
|
|
178
208
|
catch (e) {
|
|
@@ -185,12 +215,12 @@ server.registerTool("lighthouse_crm_list_options", {
|
|
|
185
215
|
description: "Get select/multi_select field options. " +
|
|
186
216
|
"Use this to discover available values for select fields before setting them on records.",
|
|
187
217
|
inputSchema: {
|
|
188
|
-
|
|
189
|
-
|
|
218
|
+
entity_type: z.enum(["company", "person", "deal", "task"]).describe("Record type"),
|
|
219
|
+
field_permalink: z.string().describe("Field permalink of the select/multi_select field"),
|
|
190
220
|
},
|
|
191
221
|
}, async (params) => {
|
|
192
222
|
try {
|
|
193
|
-
const res = await api.get(
|
|
223
|
+
const res = await api.get(`/options/${params.entity_type}/${params.field_permalink}`);
|
|
194
224
|
return text(res);
|
|
195
225
|
}
|
|
196
226
|
catch (e) {
|
|
@@ -199,17 +229,34 @@ server.registerTool("lighthouse_crm_list_options", {
|
|
|
199
229
|
});
|
|
200
230
|
server.registerTool("lighthouse_crm_create_option", {
|
|
201
231
|
title: "Create CRM Field Option",
|
|
202
|
-
description: "Add a new option
|
|
232
|
+
description: "Add a new option to a select/multi_select field. The option value is auto-generated from the label. Returns the updated list of options for the field.",
|
|
233
|
+
inputSchema: {
|
|
234
|
+
entity_type: z.enum(["company", "person", "deal", "task"]).describe("Record type"),
|
|
235
|
+
field_permalink: z.string().describe("Field permalink of the select/multi_select field"),
|
|
236
|
+
label: z.string().describe("Option display label"),
|
|
237
|
+
color: z.string().optional().describe("Option color (hex code from palette, auto-assigned if omitted)"),
|
|
238
|
+
},
|
|
239
|
+
}, async (params) => {
|
|
240
|
+
try {
|
|
241
|
+
const { entity_type, field_permalink, ...body } = params;
|
|
242
|
+
const res = await api.post(`/options/${entity_type}/${field_permalink}`, body);
|
|
243
|
+
return text(res);
|
|
244
|
+
}
|
|
245
|
+
catch (e) {
|
|
246
|
+
return err(`Failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
server.registerTool("lighthouse_crm_delete_option", {
|
|
250
|
+
title: "Delete CRM Field Option",
|
|
251
|
+
description: "Delete an option value from a select/multi_select field. Cannot delete system default options.",
|
|
203
252
|
inputSchema: {
|
|
253
|
+
entity_type: z.enum(["company", "person", "deal", "task"]).describe("Record type"),
|
|
204
254
|
field_permalink: z.string().describe("Field permalink of the select/multi_select field"),
|
|
205
|
-
|
|
206
|
-
value: z.string().describe("Option value (stored value)"),
|
|
207
|
-
label: z.string().describe("Option label (display text)"),
|
|
208
|
-
color: z.string().optional().describe("Option color (hex code)"),
|
|
255
|
+
value: z.string().describe("Option value to delete"),
|
|
209
256
|
},
|
|
210
257
|
}, async (params) => {
|
|
211
258
|
try {
|
|
212
|
-
const res = await api.
|
|
259
|
+
const res = await api.delete(`/options/${params.entity_type}/${params.field_permalink}/${params.value}`);
|
|
213
260
|
return text(res);
|
|
214
261
|
}
|
|
215
262
|
catch (e) {
|
|
@@ -225,7 +272,7 @@ server.registerTool("lighthouse_crm_search_records", {
|
|
|
225
272
|
"for the entity_type, then use those keys in your filter conditions. " +
|
|
226
273
|
"NOT for discovering new companies/people — use lighthouse_discovery_* tools for that.",
|
|
227
274
|
inputSchema: {
|
|
228
|
-
type: z.enum(["company", "person", "deal"]).describe("Record type"),
|
|
275
|
+
type: z.enum(["company", "person", "deal", "task"]).describe("Record type"),
|
|
229
276
|
filters: z
|
|
230
277
|
.record(z.unknown())
|
|
231
278
|
.optional()
|
|
@@ -261,7 +308,7 @@ server.registerTool("lighthouse_crm_get_record", {
|
|
|
261
308
|
title: "Get CRM Record",
|
|
262
309
|
description: "Get a single CRM record by ID with all fields and relationships.",
|
|
263
310
|
inputSchema: {
|
|
264
|
-
type: z.enum(["company", "person", "deal"]).describe("Record type"),
|
|
311
|
+
type: z.enum(["company", "person", "deal", "task"]).describe("Record type"),
|
|
265
312
|
id: z.string().uuid().describe("Record ID"),
|
|
266
313
|
},
|
|
267
314
|
}, async (params) => {
|
|
@@ -278,7 +325,7 @@ server.registerTool("lighthouse_crm_create_record", {
|
|
|
278
325
|
description: "Create a new CRM record. Required fields: " +
|
|
279
326
|
"company (name, domain), person (first_name, last_name), deal (name).",
|
|
280
327
|
inputSchema: {
|
|
281
|
-
type: z.enum(["company", "person", "deal"]).describe("Record type"),
|
|
328
|
+
type: z.enum(["company", "person", "deal", "task"]).describe("Record type"),
|
|
282
329
|
data: z.record(z.unknown()).describe("Record fields (name, domain, first_name, last_name, etc.)"),
|
|
283
330
|
attributes: z
|
|
284
331
|
.record(z.unknown())
|
|
@@ -301,7 +348,7 @@ server.registerTool("lighthouse_crm_update_record", {
|
|
|
301
348
|
title: "Update CRM Record",
|
|
302
349
|
description: "Update an existing CRM record's fields.",
|
|
303
350
|
inputSchema: {
|
|
304
|
-
type: z.enum(["company", "person", "deal"]).describe("Record type"),
|
|
351
|
+
type: z.enum(["company", "person", "deal", "task"]).describe("Record type"),
|
|
305
352
|
id: z.string().uuid().describe("Record ID"),
|
|
306
353
|
data: z.record(z.unknown()).describe("Fields to update"),
|
|
307
354
|
attributes: z.record(z.unknown()).optional().describe("Custom field values to update (keyed by field_permalink)"),
|
|
@@ -322,7 +369,7 @@ server.registerTool("lighthouse_crm_delete_record", {
|
|
|
322
369
|
title: "Delete CRM Record",
|
|
323
370
|
description: "Permanently delete a CRM record.",
|
|
324
371
|
inputSchema: {
|
|
325
|
-
type: z.enum(["company", "person", "deal"]).describe("Record type"),
|
|
372
|
+
type: z.enum(["company", "person", "deal", "task"]).describe("Record type"),
|
|
326
373
|
id: z.string().uuid().describe("Record ID"),
|
|
327
374
|
},
|
|
328
375
|
}, async (params) => {
|
|
@@ -340,7 +387,9 @@ server.registerTool("lighthouse_crm_create_list", {
|
|
|
340
387
|
description: "Create a new CRM list to organize records.",
|
|
341
388
|
inputSchema: {
|
|
342
389
|
name: z.string().describe("List name"),
|
|
343
|
-
|
|
390
|
+
type: z.enum(["company", "person", "deal", "task"]).describe("Record type for this list"),
|
|
391
|
+
sharing: z.enum(["private", "workspace"]).default("private").optional().describe("Visibility: 'private' or 'workspace'"),
|
|
392
|
+
color: z.string().optional().describe("Hex color code for the list"),
|
|
344
393
|
},
|
|
345
394
|
}, async (params) => {
|
|
346
395
|
try {
|
|
@@ -385,6 +434,8 @@ server.registerTool("lighthouse_crm_update_list", {
|
|
|
385
434
|
inputSchema: {
|
|
386
435
|
id: z.string().uuid().describe("List ID"),
|
|
387
436
|
name: z.string().optional().describe("New list name"),
|
|
437
|
+
sharing: z.enum(["private", "workspace"]).optional().describe("New visibility setting"),
|
|
438
|
+
color: z.string().optional().describe("New hex color code"),
|
|
388
439
|
},
|
|
389
440
|
}, async (params) => {
|
|
390
441
|
try {
|
|
@@ -439,7 +490,7 @@ server.registerTool("lighthouse_crm_add_to_list", {
|
|
|
439
490
|
inputSchema: {
|
|
440
491
|
list_id: z.string().uuid().describe("List ID"),
|
|
441
492
|
record_id: z.string().uuid().describe("Record ID to add"),
|
|
442
|
-
type: z.enum(["company", "person", "deal"]).describe("Record type"),
|
|
493
|
+
type: z.enum(["company", "person", "deal", "task"]).describe("Record type"),
|
|
443
494
|
},
|
|
444
495
|
}, async (params) => {
|
|
445
496
|
try {
|
|
@@ -474,8 +525,8 @@ server.registerTool("lighthouse_crm_list_notes", {
|
|
|
474
525
|
title: "List Notes",
|
|
475
526
|
description: "Get notes for a CRM record.",
|
|
476
527
|
inputSchema: {
|
|
477
|
-
record_id: z.string().uuid().describe("Record ID to
|
|
478
|
-
record_type: z.enum(["company", "person", "deal"]).describe("Record type"),
|
|
528
|
+
record_id: z.string().uuid().optional().describe("Record ID to filter notes by (required)"),
|
|
529
|
+
record_type: z.enum(["company", "person", "deal", "task"]).optional().describe("Record type: company, person, or deal (required)"),
|
|
479
530
|
limit: z.number().min(1).max(100).default(25),
|
|
480
531
|
offset: z.number().min(0).default(0),
|
|
481
532
|
},
|
|
@@ -500,7 +551,7 @@ server.registerTool("lighthouse_crm_create_note", {
|
|
|
500
551
|
"Tagged users receive an in-app notification.",
|
|
501
552
|
inputSchema: {
|
|
502
553
|
record_id: z.string().uuid().describe("Record ID to attach the note to"),
|
|
503
|
-
record_type: z.enum(["company", "person", "deal"]).describe("Record type"),
|
|
554
|
+
record_type: z.enum(["company", "person", "deal", "task"]).describe("Record type"),
|
|
504
555
|
title: z.string().describe("Note title"),
|
|
505
556
|
content: z.string().describe("Note content (plain text or HTML). Use <p> tags for paragraphs. For @mentions, include mention spans (see description)."),
|
|
506
557
|
tagged_users: z
|
|
@@ -699,7 +750,7 @@ server.registerTool("lighthouse_crm_list_views", {
|
|
|
699
750
|
title: "List CRM Views",
|
|
700
751
|
description: "Get all saved CRM views. Views store filter/sort configurations that can be loaded in search_records.",
|
|
701
752
|
inputSchema: {
|
|
702
|
-
entity_type: z.enum(["company", "person", "deal"]).optional().describe("Filter by record type"),
|
|
753
|
+
entity_type: z.enum(["company", "person", "deal", "task"]).optional().describe("Filter by record type"),
|
|
703
754
|
},
|
|
704
755
|
}, async (params) => {
|
|
705
756
|
try {
|
|
@@ -720,7 +771,7 @@ server.registerTool("lighthouse_crm_create_view", {
|
|
|
720
771
|
"The saved filters will auto-apply when search_records is called with this view_id.",
|
|
721
772
|
inputSchema: {
|
|
722
773
|
name: z.string().describe("View name"),
|
|
723
|
-
entity_type: z.enum(["company", "person", "deal"]).describe("Record type"),
|
|
774
|
+
entity_type: z.enum(["company", "person", "deal", "task"]).describe("Record type"),
|
|
724
775
|
filters: z
|
|
725
776
|
.record(z.unknown())
|
|
726
777
|
.optional()
|
|
@@ -729,6 +780,7 @@ server.registerTool("lighthouse_crm_create_view", {
|
|
|
729
780
|
view_type: z.enum(["table", "kanban"]).default("table").describe("View layout type"),
|
|
730
781
|
grouped_by: z.string().optional().describe("Field key to group by (required for kanban views)"),
|
|
731
782
|
sharing: z.enum(["private", "workspace"]).default("private").describe("Visibility"),
|
|
783
|
+
team_ids: z.array(z.string().uuid()).optional().describe("Team UUIDs to share the view with. Replaces any existing team shares."),
|
|
732
784
|
},
|
|
733
785
|
}, async (params) => {
|
|
734
786
|
try {
|
|
@@ -751,6 +803,7 @@ server.registerTool("lighthouse_crm_update_view", {
|
|
|
751
803
|
view_type: z.enum(["table", "kanban"]).optional(),
|
|
752
804
|
grouped_by: z.string().optional().describe("Field key to group by (required for kanban views)"),
|
|
753
805
|
sharing: z.enum(["private", "workspace"]).optional(),
|
|
806
|
+
team_ids: z.array(z.string().uuid()).optional().describe("Team UUIDs to share the view with. Replaces any existing team shares."),
|
|
754
807
|
},
|
|
755
808
|
}, async (params) => {
|
|
756
809
|
try {
|
|
@@ -945,6 +998,336 @@ server.registerTool("lighthouse_discovery_search_people", {
|
|
|
945
998
|
return err(`Failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
946
999
|
}
|
|
947
1000
|
});
|
|
1001
|
+
// ─── Reports: Dashboards ─────────────────────────────────
|
|
1002
|
+
const WIDGET_CONFIG_DESCRIPTION = "Widget config object. Structure depends on report_type: " +
|
|
1003
|
+
"STANDARD: {data_source:'companies'|'deals'|'people', report_type:'standard', " +
|
|
1004
|
+
"dimension:{field:'<field_key>', is_custom_field:boolean, time_grouping?:'day'|'week'|'month'|'quarter'|'year'}, " +
|
|
1005
|
+
"measure:{aggregation:'COUNT'|'SUM'|'AVG'|'MIN'|'MAX', field:'*'|'<field_key>', is_custom_field:boolean}, " +
|
|
1006
|
+
"segment_by?:{field:'<field_key>', is_custom_field:boolean}, " +
|
|
1007
|
+
"filter?:{operator:'AND'|'OR', conditions:[...], groups:[...]}, " +
|
|
1008
|
+
"date_range?:{type:'relative', relative_period:'all_time'|'last_7_days'|'last_30_days'|'last_90_days'|'this_month'|'last_month'|'this_quarter'|'last_quarter'|'this_year'|'last_year'} " +
|
|
1009
|
+
"OR {type:'absolute', start_date:'YYYY-MM-DD', end_date:'YYYY-MM-DD'}, " +
|
|
1010
|
+
"included_stages?:['value1','value2'], show_axis_labels?:boolean, show_zeros?:boolean, sort_by_stage_order?:boolean}. " +
|
|
1011
|
+
"FUNNEL: {report_type:'funnel', entity_type:'company'|'deal'|'person', stage_field:'<field_key>', " +
|
|
1012
|
+
"included_stages?:['stage1','stage2'], date_range?:{...}, filter?:{...}}. " +
|
|
1013
|
+
"HISTORICAL: {report_type:'stage_changes', entity_type:'company'|'deal'|'person', " +
|
|
1014
|
+
"field_permalink:'<field_key>', time_grouping?:'day'|'week'|'month'|'quarter'|'year', date_range?:{...}}. " +
|
|
1015
|
+
"ALWAYS call lighthouse_crm_get_attributes first to discover valid field keys for dimension, measure, and stage_field.";
|
|
1016
|
+
server.registerTool("lighthouse_reports_list_dashboards", {
|
|
1017
|
+
title: "List Dashboards",
|
|
1018
|
+
description: "List all report dashboards accessible to the current user. " +
|
|
1019
|
+
"Returns dashboards you own, workspace-shared dashboards, and team-shared dashboards. " +
|
|
1020
|
+
"Each dashboard includes: id, name, description, sharing (private/workspace), is_owner, " +
|
|
1021
|
+
"owner {id, first_name, last_name, full_name}, widget_count, shared_with_teams, created_at, updated_at.",
|
|
1022
|
+
inputSchema: {},
|
|
1023
|
+
}, async () => {
|
|
1024
|
+
try {
|
|
1025
|
+
const res = await api.get("/dashboards");
|
|
1026
|
+
return text(res);
|
|
1027
|
+
}
|
|
1028
|
+
catch (e) {
|
|
1029
|
+
return err(`Failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
1030
|
+
}
|
|
1031
|
+
});
|
|
1032
|
+
server.registerTool("lighthouse_reports_create_dashboard", {
|
|
1033
|
+
title: "Create Dashboard",
|
|
1034
|
+
description: "Create a new report dashboard. Dashboards contain report widgets (charts, tables, KPIs). " +
|
|
1035
|
+
"Requires reports.create permission. Returns the full dashboard object (same format as get dashboard).",
|
|
1036
|
+
inputSchema: {
|
|
1037
|
+
name: z.string().describe("Dashboard name"),
|
|
1038
|
+
description: z.string().optional().describe("Dashboard description"),
|
|
1039
|
+
sharing: z
|
|
1040
|
+
.enum(["private", "workspace"])
|
|
1041
|
+
.default("private")
|
|
1042
|
+
.describe("Visibility: 'private' (only you) or 'workspace' (all members)"),
|
|
1043
|
+
team_ids: z
|
|
1044
|
+
.array(z.string().uuid())
|
|
1045
|
+
.optional()
|
|
1046
|
+
.describe("Team IDs to share this dashboard with"),
|
|
1047
|
+
},
|
|
1048
|
+
}, async (params) => {
|
|
1049
|
+
try {
|
|
1050
|
+
const res = await api.post("/dashboards", params);
|
|
1051
|
+
return text(res);
|
|
1052
|
+
}
|
|
1053
|
+
catch (e) {
|
|
1054
|
+
return err(`Failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
1055
|
+
}
|
|
1056
|
+
});
|
|
1057
|
+
server.registerTool("lighthouse_reports_get_dashboard", {
|
|
1058
|
+
title: "Get Dashboard",
|
|
1059
|
+
description: "Get a single dashboard by ID with all its widgets. " +
|
|
1060
|
+
"Returns: id, name, description, sharing, is_owner, owner {id, first_name, last_name, full_name}, " +
|
|
1061
|
+
"widget_count, shared_with_teams, widgets [{id, name, widget_type, config, created_at, updated_at}], created_at, updated_at.",
|
|
1062
|
+
inputSchema: {
|
|
1063
|
+
id: z.string().uuid().describe("Dashboard ID"),
|
|
1064
|
+
},
|
|
1065
|
+
}, async (params) => {
|
|
1066
|
+
try {
|
|
1067
|
+
const res = await api.get(`/dashboards/${params.id}`);
|
|
1068
|
+
return text(res);
|
|
1069
|
+
}
|
|
1070
|
+
catch (e) {
|
|
1071
|
+
return err(`Failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
1072
|
+
}
|
|
1073
|
+
});
|
|
1074
|
+
server.registerTool("lighthouse_reports_update_dashboard", {
|
|
1075
|
+
title: "Update Dashboard",
|
|
1076
|
+
description: "Update a dashboard's name, description, or sharing. Only the dashboard owner can update. " +
|
|
1077
|
+
"Returns the full dashboard object (same format as get dashboard).",
|
|
1078
|
+
inputSchema: {
|
|
1079
|
+
id: z.string().uuid().describe("Dashboard ID"),
|
|
1080
|
+
name: z.string().optional().describe("New dashboard name"),
|
|
1081
|
+
description: z.string().optional().describe("New description"),
|
|
1082
|
+
sharing: z.enum(["private", "workspace"]).optional().describe("New visibility setting"),
|
|
1083
|
+
},
|
|
1084
|
+
}, async (params) => {
|
|
1085
|
+
try {
|
|
1086
|
+
const { id, ...body } = params;
|
|
1087
|
+
const res = await api.patch(`/dashboards/${id}`, body);
|
|
1088
|
+
return text(res);
|
|
1089
|
+
}
|
|
1090
|
+
catch (e) {
|
|
1091
|
+
return err(`Failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
1092
|
+
}
|
|
1093
|
+
});
|
|
1094
|
+
server.registerTool("lighthouse_reports_delete_dashboard", {
|
|
1095
|
+
title: "Delete Dashboard",
|
|
1096
|
+
description: "Permanently delete a dashboard and all its widgets. Only the dashboard owner can delete.",
|
|
1097
|
+
inputSchema: {
|
|
1098
|
+
id: z.string().uuid().describe("Dashboard ID"),
|
|
1099
|
+
},
|
|
1100
|
+
}, async (params) => {
|
|
1101
|
+
try {
|
|
1102
|
+
const res = await api.delete(`/dashboards/${params.id}`);
|
|
1103
|
+
return text(res);
|
|
1104
|
+
}
|
|
1105
|
+
catch (e) {
|
|
1106
|
+
return err(`Failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
1107
|
+
}
|
|
1108
|
+
});
|
|
1109
|
+
server.registerTool("lighthouse_reports_refresh_dashboard", {
|
|
1110
|
+
title: "Refresh Dashboard Data",
|
|
1111
|
+
description: "Refresh/fetch report data for all widgets in a dashboard. " +
|
|
1112
|
+
"Returns a map of { widget_id: report_data } for each widget.",
|
|
1113
|
+
inputSchema: {
|
|
1114
|
+
id: z.string().uuid().describe("Dashboard ID"),
|
|
1115
|
+
},
|
|
1116
|
+
}, async (params) => {
|
|
1117
|
+
try {
|
|
1118
|
+
const res = await api.post(`/dashboards/${params.id}/refresh`);
|
|
1119
|
+
return text(res);
|
|
1120
|
+
}
|
|
1121
|
+
catch (e) {
|
|
1122
|
+
return err(`Failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
1123
|
+
}
|
|
1124
|
+
});
|
|
1125
|
+
// ─── Reports: Widgets ────────────────────────────────────
|
|
1126
|
+
server.registerTool("lighthouse_reports_list_widgets", {
|
|
1127
|
+
title: "List Dashboard Widgets",
|
|
1128
|
+
description: "Get all widgets for a dashboard. " +
|
|
1129
|
+
"Each widget includes: id, name, widget_type, config, created_at, updated_at.",
|
|
1130
|
+
inputSchema: {
|
|
1131
|
+
id: z.string().uuid().describe("Dashboard ID"),
|
|
1132
|
+
},
|
|
1133
|
+
}, async (params) => {
|
|
1134
|
+
try {
|
|
1135
|
+
const res = await api.get(`/dashboards/${params.id}/widgets`);
|
|
1136
|
+
return text(res);
|
|
1137
|
+
}
|
|
1138
|
+
catch (e) {
|
|
1139
|
+
return err(`Failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
1140
|
+
}
|
|
1141
|
+
});
|
|
1142
|
+
server.registerTool("lighthouse_reports_create_widget", {
|
|
1143
|
+
title: "Create Report Widget",
|
|
1144
|
+
description: "Create a report widget (chart/table/KPI) on a dashboard. " +
|
|
1145
|
+
"WORKFLOW: 1) Call lighthouse_crm_get_attributes to discover field keys for the entity type, " +
|
|
1146
|
+
"2) Build a config object using those keys, 3) Create the widget. " +
|
|
1147
|
+
"Widget types: bar, line, pie, table, kpi, funnel, area. " +
|
|
1148
|
+
"Report types: standard (aggregate by field), funnel (pipeline conversion), stage_changes (historical transitions). " +
|
|
1149
|
+
"Returns: {id, name, widget_type, config, created_at, updated_at}.",
|
|
1150
|
+
inputSchema: {
|
|
1151
|
+
dashboard_id: z.string().uuid().describe("Dashboard ID to add widget to"),
|
|
1152
|
+
name: z.string().describe("Widget/report name"),
|
|
1153
|
+
widget_type: z
|
|
1154
|
+
.enum(["bar", "line", "pie", "table", "kpi", "funnel", "area"])
|
|
1155
|
+
.describe("Visualization type"),
|
|
1156
|
+
config: z.record(z.unknown()).describe(WIDGET_CONFIG_DESCRIPTION),
|
|
1157
|
+
position: z
|
|
1158
|
+
.record(z.unknown())
|
|
1159
|
+
.optional()
|
|
1160
|
+
.describe("Grid position: {x: number, y: number, w: number, h: number}"),
|
|
1161
|
+
},
|
|
1162
|
+
}, async (params) => {
|
|
1163
|
+
try {
|
|
1164
|
+
const { dashboard_id, ...body } = params;
|
|
1165
|
+
const res = await api.post(`/dashboards/${dashboard_id}/widgets`, body);
|
|
1166
|
+
return text(res);
|
|
1167
|
+
}
|
|
1168
|
+
catch (e) {
|
|
1169
|
+
return err(`Failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
1170
|
+
}
|
|
1171
|
+
});
|
|
1172
|
+
server.registerTool("lighthouse_reports_update_widget", {
|
|
1173
|
+
title: "Update Report Widget",
|
|
1174
|
+
description: "Update a report widget's name, type, config, or position. " +
|
|
1175
|
+
"Only provide fields you want to change — others are preserved. " +
|
|
1176
|
+
"Returns: {id, name, widget_type, config, created_at, updated_at}.",
|
|
1177
|
+
inputSchema: {
|
|
1178
|
+
dashboard_id: z.string().uuid().describe("Dashboard ID"),
|
|
1179
|
+
widget_id: z.string().uuid().describe("Widget ID"),
|
|
1180
|
+
name: z.string().optional().describe("New widget name"),
|
|
1181
|
+
widget_type: z
|
|
1182
|
+
.enum(["bar", "line", "pie", "table", "kpi", "funnel", "area"])
|
|
1183
|
+
.optional()
|
|
1184
|
+
.describe("New visualization type"),
|
|
1185
|
+
config: z.record(z.unknown()).optional().describe(WIDGET_CONFIG_DESCRIPTION),
|
|
1186
|
+
position: z.record(z.unknown()).optional().describe("New grid position: {x, y, w, h}"),
|
|
1187
|
+
},
|
|
1188
|
+
}, async (params) => {
|
|
1189
|
+
try {
|
|
1190
|
+
const { dashboard_id, widget_id, ...body } = params;
|
|
1191
|
+
const res = await api.patch(`/dashboards/${dashboard_id}/widgets/${widget_id}`, body);
|
|
1192
|
+
return text(res);
|
|
1193
|
+
}
|
|
1194
|
+
catch (e) {
|
|
1195
|
+
return err(`Failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
1196
|
+
}
|
|
1197
|
+
});
|
|
1198
|
+
server.registerTool("lighthouse_reports_delete_widget", {
|
|
1199
|
+
title: "Delete Report Widget",
|
|
1200
|
+
description: "Permanently delete a report widget from a dashboard.",
|
|
1201
|
+
inputSchema: {
|
|
1202
|
+
dashboard_id: z.string().uuid().describe("Dashboard ID"),
|
|
1203
|
+
widget_id: z.string().uuid().describe("Widget ID"),
|
|
1204
|
+
},
|
|
1205
|
+
}, async (params) => {
|
|
1206
|
+
try {
|
|
1207
|
+
const res = await api.delete(`/dashboards/${params.dashboard_id}/widgets/${params.widget_id}`);
|
|
1208
|
+
return text(res);
|
|
1209
|
+
}
|
|
1210
|
+
catch (e) {
|
|
1211
|
+
return err(`Failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
1212
|
+
}
|
|
1213
|
+
});
|
|
1214
|
+
server.registerTool("lighthouse_reports_get_widget_data", {
|
|
1215
|
+
title: "Get Widget Report Data",
|
|
1216
|
+
description: "Fetch the aggregated report data for a specific widget. " +
|
|
1217
|
+
"Returns the computed data based on the widget's config (dimensions, measures, segments, filters). " +
|
|
1218
|
+
"For standard reports: array of {dimension, measure, segment?} rows. " +
|
|
1219
|
+
"For funnel reports: array of {stage, count} rows. " +
|
|
1220
|
+
"For historical reports: array of {period, from_stage, to_stage, transition_count} rows.",
|
|
1221
|
+
inputSchema: {
|
|
1222
|
+
dashboard_id: z.string().uuid().describe("Dashboard ID"),
|
|
1223
|
+
widget_id: z.string().uuid().describe("Widget ID"),
|
|
1224
|
+
},
|
|
1225
|
+
}, async (params) => {
|
|
1226
|
+
try {
|
|
1227
|
+
const res = await api.get(`/dashboards/${params.dashboard_id}/widgets/${params.widget_id}/data`);
|
|
1228
|
+
return text(res);
|
|
1229
|
+
}
|
|
1230
|
+
catch (e) {
|
|
1231
|
+
return err(`Failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
1232
|
+
}
|
|
1233
|
+
});
|
|
1234
|
+
// ─── Sharing: Dashboard Teams ─────────────────────────────
|
|
1235
|
+
server.registerTool("lighthouse_reports_share_dashboard_with_teams", {
|
|
1236
|
+
title: "Share Dashboard with Teams",
|
|
1237
|
+
description: "Grant team-level access to a dashboard. Only the dashboard owner can share. " +
|
|
1238
|
+
"Use lighthouse_workspace_list_teams to find team IDs first. " +
|
|
1239
|
+
"Requires reports.edit permission.",
|
|
1240
|
+
inputSchema: {
|
|
1241
|
+
id: z.string().uuid().describe("Dashboard ID"),
|
|
1242
|
+
team_ids: z.array(z.string().uuid()).describe("Array of team UUIDs to grant access to"),
|
|
1243
|
+
},
|
|
1244
|
+
}, async (params) => {
|
|
1245
|
+
try {
|
|
1246
|
+
const { id, ...body } = params;
|
|
1247
|
+
const res = await api.post(`/dashboards/${id}/teams`, body);
|
|
1248
|
+
return text(res);
|
|
1249
|
+
}
|
|
1250
|
+
catch (e) {
|
|
1251
|
+
return err(`Failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
1252
|
+
}
|
|
1253
|
+
});
|
|
1254
|
+
server.registerTool("lighthouse_reports_revoke_dashboard_from_teams", {
|
|
1255
|
+
title: "Revoke Dashboard Team Access",
|
|
1256
|
+
description: "Revoke team-level access from a dashboard. Only the dashboard owner can revoke. " +
|
|
1257
|
+
"Requires reports.edit permission.",
|
|
1258
|
+
inputSchema: {
|
|
1259
|
+
id: z.string().uuid().describe("Dashboard ID"),
|
|
1260
|
+
team_ids: z.array(z.string().uuid()).describe("Array of team UUIDs to revoke access from"),
|
|
1261
|
+
},
|
|
1262
|
+
}, async (params) => {
|
|
1263
|
+
try {
|
|
1264
|
+
const { id, ...body } = params;
|
|
1265
|
+
const res = await api.delete(`/dashboards/${id}/teams`, body);
|
|
1266
|
+
return text(res);
|
|
1267
|
+
}
|
|
1268
|
+
catch (e) {
|
|
1269
|
+
return err(`Failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
1270
|
+
}
|
|
1271
|
+
});
|
|
1272
|
+
// ─── Sharing: View Teams ──────────────────────────────────
|
|
1273
|
+
server.registerTool("lighthouse_crm_share_view_with_teams", {
|
|
1274
|
+
title: "Share View with Teams",
|
|
1275
|
+
description: "Grant team-level access to a CRM view. Only the view owner can share. " +
|
|
1276
|
+
"Use lighthouse_workspace_list_teams to find team IDs first. " +
|
|
1277
|
+
"Requires views.share permission. " +
|
|
1278
|
+
"Returns formatted view: {id, name, entity_type, view_type, filters, sort, grouped_by, sharing, owner, shared_with_teams, created_at}.",
|
|
1279
|
+
inputSchema: {
|
|
1280
|
+
id: z.string().uuid().describe("View ID"),
|
|
1281
|
+
team_ids: z.array(z.string().uuid()).describe("Array of team UUIDs to grant access to"),
|
|
1282
|
+
},
|
|
1283
|
+
}, async (params) => {
|
|
1284
|
+
try {
|
|
1285
|
+
const { id, ...body } = params;
|
|
1286
|
+
const res = await api.post(`/views/${id}/teams`, body);
|
|
1287
|
+
return text(res);
|
|
1288
|
+
}
|
|
1289
|
+
catch (e) {
|
|
1290
|
+
return err(`Failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
1291
|
+
}
|
|
1292
|
+
});
|
|
1293
|
+
server.registerTool("lighthouse_crm_revoke_view_from_teams", {
|
|
1294
|
+
title: "Revoke View Team Access",
|
|
1295
|
+
description: "Revoke team-level access from a CRM view. Only the view owner can revoke. " +
|
|
1296
|
+
"Requires views.share permission. " +
|
|
1297
|
+
"Returns formatted view: {id, name, entity_type, view_type, filters, sort, grouped_by, sharing, owner, shared_with_teams, created_at}.",
|
|
1298
|
+
inputSchema: {
|
|
1299
|
+
id: z.string().uuid().describe("View ID"),
|
|
1300
|
+
team_ids: z.array(z.string().uuid()).describe("Array of team UUIDs to revoke access from"),
|
|
1301
|
+
},
|
|
1302
|
+
}, async (params) => {
|
|
1303
|
+
try {
|
|
1304
|
+
const { id, ...body } = params;
|
|
1305
|
+
const res = await api.delete(`/views/${id}/teams`, body);
|
|
1306
|
+
return text(res);
|
|
1307
|
+
}
|
|
1308
|
+
catch (e) {
|
|
1309
|
+
return err(`Failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
1310
|
+
}
|
|
1311
|
+
});
|
|
1312
|
+
server.registerTool("lighthouse_crm_update_view_sharing", {
|
|
1313
|
+
title: "Update View Sharing Status",
|
|
1314
|
+
description: "Change a CRM view's sharing visibility. Setting to 'private' also removes all team permissions. " +
|
|
1315
|
+
"Only the view owner can change sharing. Requires views.share permission. " +
|
|
1316
|
+
"Returns formatted view: {id, name, entity_type, view_type, filters, sort, grouped_by, sharing, owner, shared_with_teams, created_at}.",
|
|
1317
|
+
inputSchema: {
|
|
1318
|
+
id: z.string().uuid().describe("View ID"),
|
|
1319
|
+
sharing: z.enum(["private", "workspace"]).describe("New sharing visibility"),
|
|
1320
|
+
},
|
|
1321
|
+
}, async (params) => {
|
|
1322
|
+
try {
|
|
1323
|
+
const { id, ...body } = params;
|
|
1324
|
+
const res = await api.patch(`/views/${id}/sharing`, body);
|
|
1325
|
+
return text(res);
|
|
1326
|
+
}
|
|
1327
|
+
catch (e) {
|
|
1328
|
+
return err(`Failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
1329
|
+
}
|
|
1330
|
+
});
|
|
948
1331
|
// ─── Start ───────────────────────────────────────────────
|
|
949
1332
|
async function main() {
|
|
950
1333
|
const transport = new StdioServerTransport();
|