@centrali-io/centrali-mcp 5.2.0 → 5.4.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.
@@ -2,7 +2,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { CentraliSDK } from "@centrali-io/centrali-sdk";
3
3
  import axios, { AxiosInstance } from "axios";
4
4
  import { z } from "zod";
5
-
5
+ import { registerTool, formatError } from "./_register.js";
6
6
  /**
7
7
  * Ensures the SDK has a valid token by making a lightweight SDK call if needed.
8
8
  */
@@ -62,22 +62,6 @@ function createIamClient(sdk: CentraliSDK, centraliUrl: string, workspaceId: str
62
62
  return client;
63
63
  }
64
64
 
65
- function formatError(error: unknown, context: string): string {
66
- if (error && typeof error === "object") {
67
- const e = error as Record<string, any>;
68
- if (e.response?.data) {
69
- const d = e.response.data;
70
- const code = d.code ?? d.error?.code ?? e.response.status ?? "ERROR";
71
- const message = d.message ?? d.error?.message ?? JSON.stringify(d);
72
- return `Error ${context}: [${code}] ${message}`;
73
- }
74
- if ("message" in e) {
75
- return `Error ${context}: ${e.message}`;
76
- }
77
- }
78
- return `Error ${context}: ${error instanceof Error ? error.message : String(error)}`;
79
- }
80
-
81
65
  export interface CurrentIdentityContext {
82
66
  clientId?: string;
83
67
  userId?: string;
@@ -99,7 +83,7 @@ export function registerServiceAccountTools(
99
83
 
100
84
  // ── Identity ─────────────────────────────────────────────────────
101
85
 
102
- server.tool(
86
+ registerTool<any>(server,
103
87
  "get_current_identity",
104
88
  "Get the current authenticated MCP identity. In stdio/service-account mode, returns the MCP service account. In hosted OAuth mode, fetches the authenticated user's profile, roles, and groups from IAM.",
105
89
  {},
@@ -178,7 +162,7 @@ export function registerServiceAccountTools(
178
162
 
179
163
  // ── Service Account CRUD ─────────────────────────────────────────
180
164
 
181
- server.tool(
165
+ registerTool<any>(server,
182
166
  "list_service_accounts",
183
167
  "List all service accounts in the workspace. Service accounts are machine identities used for backend-to-backend API access (client_credentials flow).",
184
168
  {
@@ -203,7 +187,7 @@ export function registerServiceAccountTools(
203
187
  }
204
188
  );
205
189
 
206
- server.tool(
190
+ registerTool<any>(server,
207
191
  "get_service_account",
208
192
  "Get details of a specific service account by its numeric ID. Returns name, clientId, description, and revocation status. Does NOT return the clientSecret (it's only shown once at creation time).",
209
193
  {
@@ -224,7 +208,7 @@ export function registerServiceAccountTools(
224
208
  }
225
209
  );
226
210
 
227
- server.tool(
211
+ registerTool<any>(server,
228
212
  "create_service_account",
229
213
  "Create a new service account (machine identity). Returns the clientId and clientSecret — the secret is ONLY shown once, so store it securely. Use the credentials with OAuth2 client_credentials flow to get access tokens.",
230
214
  {
@@ -258,7 +242,7 @@ export function registerServiceAccountTools(
258
242
  }
259
243
  );
260
244
 
261
- server.tool(
245
+ registerTool<any>(server,
262
246
  "update_service_account_name",
263
247
  "Update the display name of a service account.",
264
248
  {
@@ -280,7 +264,7 @@ export function registerServiceAccountTools(
280
264
  }
281
265
  );
282
266
 
283
- server.tool(
267
+ registerTool<any>(server,
284
268
  "update_service_account_description",
285
269
  "Update the description of a service account.",
286
270
  {
@@ -302,7 +286,7 @@ export function registerServiceAccountTools(
302
286
  }
303
287
  );
304
288
 
305
- server.tool(
289
+ registerTool<any>(server,
306
290
  "delete_service_account",
307
291
  "Permanently delete a service account. This is irreversible — all tokens are invalidated immediately. Note: the service account must not be revoked (revoke prevents deletion).",
308
292
  {
@@ -325,7 +309,7 @@ export function registerServiceAccountTools(
325
309
 
326
310
  // ── Secret Rotation & Revocation ─────────────────────────────────
327
311
 
328
- server.tool(
312
+ registerTool<any>(server,
329
313
  "rotate_service_account_secret",
330
314
  "Rotate the client secret of a service account. The old secret is immediately invalidated. Returns the new clientSecret — store it securely, it's only shown once.",
331
315
  {
@@ -356,7 +340,7 @@ export function registerServiceAccountTools(
356
340
  }
357
341
  );
358
342
 
359
- server.tool(
343
+ registerTool<any>(server,
360
344
  "revoke_service_account",
361
345
  "Revoke a service account. All existing tokens are invalidated and no new tokens can be issued. This cannot be undone.",
362
346
  {
@@ -379,7 +363,7 @@ export function registerServiceAccountTools(
379
363
 
380
364
  // ── Dev Token Generation ─────────────────────────────────────────
381
365
 
382
- server.tool(
366
+ registerTool<any>(server,
383
367
  "generate_dev_token",
384
368
  "Generate a short-lived development token for a service account. Useful for testing and local development without the full OAuth2 client_credentials flow. The token has limited TTL.",
385
369
  {
@@ -413,7 +397,7 @@ export function registerServiceAccountTools(
413
397
 
414
398
  // ── Permission Introspection ─────────────────────────────────────
415
399
 
416
- server.tool(
400
+ registerTool<any>(server,
417
401
  "scan_service_account_permissions",
418
402
  "Scan all permissions for a service account. Returns a full access matrix showing every resource and action with Allow/Deny decisions and reasons. Use this to audit what a service account can and cannot do.",
419
403
  {
@@ -439,7 +423,7 @@ export function registerServiceAccountTools(
439
423
  }
440
424
  );
441
425
 
442
- server.tool(
426
+ registerTool<any>(server,
443
427
  "simulate_service_account_permission",
444
428
  "Simulate an authorization check for a service account against a specific resource and action. Returns the decision (Allow/Deny), evaluation trace, and suggestions for granting access if denied.",
445
429
  {
@@ -490,7 +474,7 @@ export function registerServiceAccountTools(
490
474
  })),
491
475
  }).describe("The remediation option object from generate_remediation — pass the full option object exactly as returned");
492
476
 
493
- server.tool(
477
+ registerTool<any>(server,
494
478
  "generate_remediation",
495
479
  "Generate remediation options for granting a service account access to a specific resource and actions. Returns multiple options: assign an existing role, join a group, or create a minimal new policy. Use after scan_service_account_permissions or simulate_service_account_permission shows Deny.",
496
480
  {
@@ -520,7 +504,7 @@ export function registerServiceAccountTools(
520
504
  }
521
505
  );
522
506
 
523
- server.tool(
507
+ registerTool<any>(server,
524
508
  "preview_remediation",
525
509
  "Preview what changes would be made by applying a specific remediation option. Shows what would be created or modified without actually making changes. Call generate_remediation first to get the options.",
526
510
  {
@@ -553,7 +537,7 @@ export function registerServiceAccountTools(
553
537
  }
554
538
  );
555
539
 
556
- server.tool(
540
+ registerTool<any>(server,
557
541
  "apply_remediation",
558
542
  "Apply a remediation option to actually grant access. Creates roles, policies, or group assignments as needed. After applying, the service account will have the requested permissions. The response includes a verification check confirming the access was granted.",
559
543
  {
@@ -589,7 +573,7 @@ export function registerServiceAccountTools(
589
573
 
590
574
  // ── Service Account ↔ Roles ──────────────────────────────────────
591
575
 
592
- server.tool(
576
+ registerTool<any>(server,
593
577
  "list_service_account_roles",
594
578
  "List all roles assigned to a service account.",
595
579
  {
@@ -610,7 +594,7 @@ export function registerServiceAccountTools(
610
594
  }
611
595
  );
612
596
 
613
- server.tool(
597
+ registerTool<any>(server,
614
598
  "assign_role_to_service_account",
615
599
  "Assign a role to a service account. The service account inherits all permissions defined in the role.",
616
600
  {
@@ -632,7 +616,7 @@ export function registerServiceAccountTools(
632
616
  }
633
617
  );
634
618
 
635
- server.tool(
619
+ registerTool<any>(server,
636
620
  "remove_role_from_service_account",
637
621
  "Remove a role from a service account. The service account loses all permissions from this role.",
638
622
  {
@@ -656,7 +640,7 @@ export function registerServiceAccountTools(
656
640
 
657
641
  // ── Service Account ↔ Groups ─────────────────────────────────────
658
642
 
659
- server.tool(
643
+ registerTool<any>(server,
660
644
  "list_service_account_groups",
661
645
  "List all groups a service account belongs to.",
662
646
  {
@@ -677,7 +661,7 @@ export function registerServiceAccountTools(
677
661
  }
678
662
  );
679
663
 
680
- server.tool(
664
+ registerTool<any>(server,
681
665
  "add_service_account_to_group",
682
666
  "Add a service account to a group. The service account inherits all roles assigned to the group.",
683
667
  {
@@ -699,7 +683,7 @@ export function registerServiceAccountTools(
699
683
  }
700
684
  );
701
685
 
702
- server.tool(
686
+ registerTool<any>(server,
703
687
  "remove_service_account_from_group",
704
688
  "Remove a service account from a group. The service account loses all permissions inherited through this group.",
705
689
  {
@@ -723,7 +707,7 @@ export function registerServiceAccountTools(
723
707
 
724
708
  // ── Role CRUD ────────────────────────────────────────────────────
725
709
 
726
- server.tool(
710
+ registerTool<any>(server,
727
711
  "list_roles",
728
712
  "List all roles in the workspace. Roles are named labels assigned to users and service accounts.",
729
713
  {
@@ -748,7 +732,7 @@ export function registerServiceAccountTools(
748
732
  }
749
733
  );
750
734
 
751
- server.tool(
735
+ registerTool<any>(server,
752
736
  "get_role",
753
737
  "Get details of a role including its permissions.",
754
738
  {
@@ -769,7 +753,7 @@ export function registerServiceAccountTools(
769
753
  }
770
754
  );
771
755
 
772
- server.tool(
756
+ registerTool<any>(server,
773
757
  "create_role",
774
758
  "Create a new role. Roles are named labels assigned to users and service accounts. They do NOT contain permissions directly — to grant access, create a policy that targets the role as a principal. Role names are immutable after creation.",
775
759
  {
@@ -793,7 +777,7 @@ export function registerServiceAccountTools(
793
777
  }
794
778
  );
795
779
 
796
- server.tool(
780
+ registerTool<any>(server,
797
781
  "update_role",
798
782
  "Update a role's description. Role names are immutable. Roles are named labels assigned to users/service accounts — they do NOT contain permissions directly. To grant access, create a policy that references the role.",
799
783
  {
@@ -817,7 +801,7 @@ export function registerServiceAccountTools(
817
801
  }
818
802
  );
819
803
 
820
- server.tool(
804
+ registerTool<any>(server,
821
805
  "delete_role",
822
806
  "Delete a role. Service accounts assigned to this role will lose the label.",
823
807
  {
@@ -840,7 +824,7 @@ export function registerServiceAccountTools(
840
824
 
841
825
  // ── Group CRUD ───────────────────────────────────────────────────
842
826
 
843
- server.tool(
827
+ registerTool<any>(server,
844
828
  "list_groups",
845
829
  "List all groups in the workspace. Groups bundle service accounts together and can have roles assigned to them.",
846
830
  {
@@ -865,7 +849,7 @@ export function registerServiceAccountTools(
865
849
  }
866
850
  );
867
851
 
868
- server.tool(
852
+ registerTool<any>(server,
869
853
  "get_group",
870
854
  "Get details of a group.",
871
855
  {
@@ -886,7 +870,7 @@ export function registerServiceAccountTools(
886
870
  }
887
871
  );
888
872
 
889
- server.tool(
873
+ registerTool<any>(server,
890
874
  "create_group",
891
875
  "Create a new group. Groups let you assign roles to multiple service accounts at once.",
892
876
  {
@@ -910,7 +894,7 @@ export function registerServiceAccountTools(
910
894
  }
911
895
  );
912
896
 
913
- server.tool(
897
+ registerTool<any>(server,
914
898
  "update_group",
915
899
  "Update a group's description. Group names are immutable and cannot be changed after creation.",
916
900
  {
@@ -934,7 +918,7 @@ export function registerServiceAccountTools(
934
918
  }
935
919
  );
936
920
 
937
- server.tool(
921
+ registerTool<any>(server,
938
922
  "delete_group",
939
923
  "Delete a group. Service accounts in this group lose permissions inherited through it.",
940
924
  {
@@ -959,7 +943,7 @@ export function registerServiceAccountTools(
959
943
 
960
944
  const getPkClient = () => createIamClient(sdk, centraliUrl, workspaceId, "publishable-keys");
961
945
 
962
- server.tool(
946
+ registerTool<any>(server,
963
947
  "list_publishable_keys",
964
948
  "List all publishable keys in the workspace. Publishable keys are frontend-safe API keys for browser/client-side apps — they grant scoped, read-mostly access to specific collections, records, triggers, and files.",
965
949
  {
@@ -984,7 +968,7 @@ export function registerServiceAccountTools(
984
968
  }
985
969
  );
986
970
 
987
- server.tool(
971
+ registerTool<any>(server,
988
972
  "get_publishable_key",
989
973
  "Get details of a publishable key including its scopes and usage stats.",
990
974
  {
@@ -1005,7 +989,7 @@ export function registerServiceAccountTools(
1005
989
  }
1006
990
  );
1007
991
 
1008
- server.tool(
992
+ registerTool<any>(server,
1009
993
  "create_publishable_key",
1010
994
  "Create a publishable key for frontend/client-side use. Returns the full key value (pk_live_...) — it's safe to embed in client code but only shown in full once. Scopes control what the key can access. Always use least-privilege: only grant the specific collections, actions, and triggers the frontend needs.",
1011
995
  {
@@ -1037,7 +1021,7 @@ export function registerServiceAccountTools(
1037
1021
  }
1038
1022
  );
1039
1023
 
1040
- server.tool(
1024
+ registerTool<any>(server,
1041
1025
  "update_publishable_key",
1042
1026
  "Update a publishable key's label or scopes. When updating scopes, the new scopes replace all existing ones.",
1043
1027
  {
@@ -1063,7 +1047,7 @@ export function registerServiceAccountTools(
1063
1047
  }
1064
1048
  );
1065
1049
 
1066
- server.tool(
1050
+ registerTool<any>(server,
1067
1051
  "revoke_publishable_key",
1068
1052
  "Revoke a publishable key. The key immediately stops working. This cannot be undone — create a new key if needed.",
1069
1053
  {
@@ -1092,7 +1076,7 @@ export function registerServiceAccountTools(
1092
1076
  const getPermissionsClient = () => createIamClient(sdk, centraliUrl, workspaceId, "access/permissions");
1093
1077
  const getResourcesClient = () => createIamClient(sdk, centraliUrl, workspaceId, "access/resources");
1094
1078
 
1095
- server.tool(
1079
+ registerTool<any>(server,
1096
1080
  "list_policies",
1097
1081
  "List all access control policies in the workspace. Policies define who can do what — they bind roles/groups/principals to permissions with optional conditions.",
1098
1082
  {
@@ -1112,7 +1096,7 @@ export function registerServiceAccountTools(
1112
1096
  }
1113
1097
  );
1114
1098
 
1115
- server.tool(
1099
+ registerTool<any>(server,
1116
1100
  "get_policy",
1117
1101
  "Get the full definition of an access control policy by ID.",
1118
1102
  {
@@ -1128,7 +1112,7 @@ export function registerServiceAccountTools(
1128
1112
  }
1129
1113
  );
1130
1114
 
1131
- server.tool(
1115
+ registerTool<any>(server,
1132
1116
  "create_policy",
1133
1117
  "Create an access control policy. Policies grant or deny actions on resources to principals (users, service accounts, groups, roles).",
1134
1118
  {
@@ -1144,7 +1128,7 @@ export function registerServiceAccountTools(
1144
1128
  }
1145
1129
  );
1146
1130
 
1147
- server.tool(
1131
+ registerTool<any>(server,
1148
1132
  "update_policy",
1149
1133
  "Update an existing access control policy by ID.",
1150
1134
  {
@@ -1161,7 +1145,7 @@ export function registerServiceAccountTools(
1161
1145
  }
1162
1146
  );
1163
1147
 
1164
- server.tool(
1148
+ registerTool<any>(server,
1165
1149
  "delete_policy",
1166
1150
  "Delete an access control policy by ID. This immediately revokes the access it granted. Use this to undo apply_remediation.",
1167
1151
  {
@@ -1179,7 +1163,7 @@ export function registerServiceAccountTools(
1179
1163
 
1180
1164
  // ── Permissions CRUD ───────────────────────────────────────────────
1181
1165
 
1182
- server.tool(
1166
+ registerTool<any>(server,
1183
1167
  "list_permissions",
1184
1168
  "List all permission definitions in the workspace. Permissions are resource + action pairs (e.g., 'workspace::records' + 'create').",
1185
1169
  {
@@ -1199,7 +1183,7 @@ export function registerServiceAccountTools(
1199
1183
  }
1200
1184
  );
1201
1185
 
1202
- server.tool(
1186
+ registerTool<any>(server,
1203
1187
  "create_permission",
1204
1188
  "Create a new permission definition. Permissions bind actions to a resource within a policy. Required fields: name, resourceId (UUID from list_resources), actions (string array), policyId (UUID from list_policies or create_policy).",
1205
1189
  {
@@ -1215,7 +1199,7 @@ export function registerServiceAccountTools(
1215
1199
  }
1216
1200
  );
1217
1201
 
1218
- server.tool(
1202
+ registerTool<any>(server,
1219
1203
  "delete_permission",
1220
1204
  "Delete a permission definition by ID.",
1221
1205
  {
@@ -1233,7 +1217,7 @@ export function registerServiceAccountTools(
1233
1217
 
1234
1218
  // ── Resources ──────────────────────────────────────────────────────
1235
1219
 
1236
- server.tool(
1220
+ registerTool<any>(server,
1237
1221
  "list_resources",
1238
1222
  "List all protected resource definitions in the workspace. Resources are the things permissions act on (e.g., 'workspace::records', 'workspace::functions').",
1239
1223
  {
@@ -1253,7 +1237,7 @@ export function registerServiceAccountTools(
1253
1237
  }
1254
1238
  );
1255
1239
 
1256
- server.tool(
1240
+ registerTool<any>(server,
1257
1241
  "get_resource",
1258
1242
  "Get details of a protected resource definition by ID.",
1259
1243
  {
@@ -1,30 +1,9 @@
1
1
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { CentraliSDK } from "@centrali-io/centrali-sdk";
3
3
  import { z } from "zod";
4
-
5
- function formatError(error: unknown, context: string): string {
6
- if (error && typeof error === 'object') {
7
- const e = error as Record<string, any>;
8
- if ('message' in e) {
9
- let msg = `Error ${context}`;
10
- if ('code' in e || 'status' in e) {
11
- msg += `: [${e.code ?? e.status ?? 'ERROR'}] ${e.message}`;
12
- } else {
13
- msg += `: ${e.message}`;
14
- }
15
- if (Array.isArray(e.fieldErrors) && e.fieldErrors.length > 0) {
16
- msg += '\nField errors:\n' + (e.fieldErrors as Array<{field: string; message: string}>)
17
- .map(f => ` ${f.field}: ${f.message}`)
18
- .join('\n');
19
- }
20
- return msg;
21
- }
22
- }
23
- return `Error ${context}: ${error instanceof Error ? error.message : String(error)}`;
24
- }
25
-
4
+ import { registerTool, formatError } from "./_register.js";
26
5
  export function registerSmartQueryTools(server: McpServer, sdk: CentraliSDK) {
27
- server.tool(
6
+ registerTool<any>(server,
28
7
  "list_smart_queries",
29
8
  "List smart queries. Smart queries are reusable, parameterized queries defined in the Centrali console. Optionally filter by collection record slug.",
30
9
  {
@@ -59,7 +38,7 @@ export function registerSmartQueryTools(server: McpServer, sdk: CentraliSDK) {
59
38
  }
60
39
  );
61
40
 
62
- server.tool(
41
+ registerTool<any>(server,
63
42
  "execute_smart_query",
64
43
  "Execute a smart query by ID and return the results. Smart queries can have parameterized variables using {{variableName}} syntax.",
65
44
  {
@@ -101,7 +80,7 @@ export function registerSmartQueryTools(server: McpServer, sdk: CentraliSDK) {
101
80
  }
102
81
  );
103
82
 
104
- server.tool(
83
+ registerTool<any>(server,
105
84
  "get_smart_query",
106
85
  "Get a smart query by ID. Returns the full query definition including filters, sort, and variable declarations.",
107
86
  {
@@ -130,7 +109,7 @@ export function registerSmartQueryTools(server: McpServer, sdk: CentraliSDK) {
130
109
  }
131
110
  );
132
111
 
133
- server.tool(
112
+ registerTool<any>(server,
134
113
  "create_smart_query",
135
114
  "Create a new smart query for a collection. Smart queries are reusable, parameterized queries with filter, sort, and variable support.",
136
115
  {
@@ -166,7 +145,7 @@ export function registerSmartQueryTools(server: McpServer, sdk: CentraliSDK) {
166
145
  }
167
146
  );
168
147
 
169
- server.tool(
148
+ registerTool<any>(server,
170
149
  "update_smart_query",
171
150
  "Update an existing smart query. Only include the fields you want to change.",
172
151
  {
@@ -206,7 +185,7 @@ export function registerSmartQueryTools(server: McpServer, sdk: CentraliSDK) {
206
185
  }
207
186
  );
208
187
 
209
- server.tool(
188
+ registerTool<any>(server,
210
189
  "delete_smart_query",
211
190
  "Delete a smart query by ID.",
212
191
  {
@@ -238,7 +217,7 @@ export function registerSmartQueryTools(server: McpServer, sdk: CentraliSDK) {
238
217
  }
239
218
  );
240
219
 
241
- server.tool(
220
+ registerTool<any>(server,
242
221
  "test_smart_query",
243
222
  "Test execute a query definition without saving it. Useful for validating query syntax and previewing results before creating a smart query.",
244
223
  {
@@ -2,45 +2,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
2
  import { CentraliSDK } from "@centrali-io/centrali-sdk";
3
3
  import axios, { AxiosInstance } from "axios";
4
4
  import { z } from "zod";
5
-
6
- function formatError(error: unknown, context: string): string {
7
- if (error && typeof error === 'object') {
8
- const e = error as Record<string, any>;
9
- if (e.response?.data) {
10
- const d = e.response.data;
11
- const code = d.code ?? d.errorCode ?? d.error?.code ?? e.response.status ?? "ERROR";
12
- const message = d.message ?? d.error?.message ?? JSON.stringify(d);
13
- let msg = `Error ${context}: [${code}] ${message}`;
14
- // Include extra context from error response (e.g. classification details)
15
- if (d.classification) {
16
- msg += `\nClassification: ${JSON.stringify(d.classification)}`;
17
- }
18
- if (d.criticalChanges) {
19
- msg += `\nCritical changes: ${JSON.stringify(d.criticalChanges)}`;
20
- }
21
- if (d.suggestion) {
22
- msg += `\nSuggestion: ${d.suggestion}`;
23
- }
24
- return msg;
25
- }
26
- if ('message' in e) {
27
- let msg = `Error ${context}`;
28
- if ('code' in e || 'status' in e) {
29
- msg += `: [${e.code ?? e.status ?? 'ERROR'}] ${e.message}`;
30
- } else {
31
- msg += `: ${e.message}`;
32
- }
33
- if (Array.isArray(e.fieldErrors) && e.fieldErrors.length > 0) {
34
- msg += '\nField errors:\n' + (e.fieldErrors as Array<{field: string; message: string}>)
35
- .map(f => ` ${f.field}: ${f.message}`)
36
- .join('\n');
37
- }
38
- return msg;
39
- }
40
- }
41
- return `Error ${context}: ${error instanceof Error ? error.message : String(error)}`;
42
- }
43
-
5
+ import { registerTool, formatError } from "./_register.js";
44
6
  /**
45
7
  * Ensures the SDK has a valid token.
46
8
  */
@@ -99,7 +61,7 @@ function createDataClient(sdk: CentraliSDK, centraliUrl: string, workspaceId: st
99
61
  }
100
62
 
101
63
  export function registerStructureTools(server: McpServer, sdk: CentraliSDK) {
102
- server.tool(
64
+ registerTool<any>(server,
103
65
  "list_structures",
104
66
  "[DEPRECATED: use list_collections instead] List all data structures (schemas) in the Centrali workspace. Returns name, slug, description, and property definitions for each structure.",
105
67
  {
@@ -128,7 +90,7 @@ export function registerStructureTools(server: McpServer, sdk: CentraliSDK) {
128
90
  }
129
91
  );
130
92
 
131
- server.tool(
93
+ registerTool<any>(server,
132
94
  "get_structure",
133
95
  "[DEPRECATED: use get_collection instead] Get the full schema definition for a specific structure by its record slug. Returns properties, types, constraints, and configuration.",
134
96
  {
@@ -162,7 +124,7 @@ export function registerStructureTools(server: McpServer, sdk: CentraliSDK) {
162
124
  export function registerCollectionTools(server: McpServer, sdk: CentraliSDK, centraliUrl: string, workspaceId: string) {
163
125
  const getCollectionsClient = () => createDataClient(sdk, centraliUrl, workspaceId, "collections");
164
126
 
165
- server.tool(
127
+ registerTool<any>(server,
166
128
  "list_collections",
167
129
  "List all data collections (schemas) in the Centrali workspace. Returns name, slug, description, and property definitions for each collection.",
168
130
  {
@@ -191,7 +153,7 @@ export function registerCollectionTools(server: McpServer, sdk: CentraliSDK, cen
191
153
  }
192
154
  );
193
155
 
194
- server.tool(
156
+ registerTool<any>(server,
195
157
  "get_collection",
196
158
  "Get the full schema definition for a specific collection by its record slug. Returns properties, types, constraints, and configuration.",
197
159
  {
@@ -221,7 +183,7 @@ export function registerCollectionTools(server: McpServer, sdk: CentraliSDK, cen
221
183
  }
222
184
  );
223
185
 
224
- server.tool(
186
+ registerTool<any>(server,
225
187
  "create_collection",
226
188
  "Create a new data collection (schema). Define the name, recordSlug, description, and properties (fields) for the collection.",
227
189
  {
@@ -283,7 +245,7 @@ export function registerCollectionTools(server: McpServer, sdk: CentraliSDK, cen
283
245
  // update_collection handles everything automatically. For breaking or
284
246
  // critical changes, analyze first to understand what's needed.
285
247
 
286
- server.tool(
248
+ registerTool<any>(server,
287
249
  "analyze_collection_update",
288
250
  `Analyze proposed schema changes BEFORE applying them. Returns whether migration is needed, what changes are breaking/critical, suggested fixes, and estimated duration.
289
251
 
@@ -351,7 +313,7 @@ RESPONSE FIELDS:
351
313
  }
352
314
  );
353
315
 
354
- server.tool(
316
+ registerTool<any>(server,
355
317
  "preview_collection_migration",
356
318
  `Preview the effect of migration fixes on sample records BEFORE applying them. Shows before/after snapshots so you can verify fixes are correct.
357
319
 
@@ -382,7 +344,7 @@ WHEN TO USE: After analyze_collection_update returns suggestedFixes, call this t
382
344
  }
383
345
  );
384
346
 
385
- server.tool(
347
+ registerTool<any>(server,
386
348
  "update_collection",
387
349
  `Update a collection's schema using the safe upgrade endpoint. This handles both simple updates and complex migrations.
388
350
 
@@ -487,7 +449,7 @@ Each fix is an object with: { fieldName, fixType, value?, expression?, applyToAl
487
449
  }
488
450
  );
489
451
 
490
- server.tool(
452
+ registerTool<any>(server,
491
453
  "get_collection_upgrade_progress",
492
454
  "Check the progress of an async collection migration/upgrade job. Call this after update_collection returns status='in_progress'.",
493
455
  {
@@ -510,7 +472,7 @@ Each fix is an object with: { fieldName, fixType, value?, expression?, applyToAl
510
472
  }
511
473
  );
512
474
 
513
- server.tool(
475
+ registerTool<any>(server,
514
476
  "delete_collection",
515
477
  "Delete a collection by ID. This permanently removes the collection schema and all its records.",
516
478
  {
@@ -541,7 +503,7 @@ Each fix is an object with: { fieldName, fixType, value?, expression?, applyToAl
541
503
  }
542
504
  );
543
505
 
544
- server.tool(
506
+ registerTool<any>(server,
545
507
  "explore_collections",
546
508
  "Get a compact overview of ALL collections in the workspace with their field names, types, and constraints. Returns everything in one call — no need to list collections and then get each one separately.",
547
509
  {