@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.
- package/README.md +15 -0
- package/dist/index.js +2 -0
- package/dist/tools/_register.d.ts +24 -0
- package/dist/tools/_register.js +44 -0
- package/dist/tools/auth-providers.js +15 -30
- package/dist/tools/compute.js +48 -69
- package/dist/tools/describe.js +174 -21
- package/dist/tools/insights.js +13 -36
- package/dist/tools/orchestrations.js +21 -44
- package/dist/tools/pages.js +39 -61
- package/dist/tools/records.js +29 -50
- package/dist/tools/search.js +3 -24
- package/dist/tools/service-accounts.js +93 -108
- package/dist/tools/smart-queries.js +15 -36
- package/dist/tools/structures.js +23 -61
- package/dist/tools/validation.js +11 -34
- package/dist/tools/webhook-subscriptions.d.ts +3 -0
- package/dist/tools/webhook-subscriptions.js +292 -0
- package/package.json +5 -6
- package/src/index.ts +2 -0
- package/src/tools/_register.ts +53 -0
- package/src/tools/auth-providers.ts +8 -24
- package/src/tools/compute.ts +25 -46
- package/src/tools/describe.ts +200 -21
- package/src/tools/insights.ts +19 -28
- package/src/tools/orchestrations.ts +11 -34
- package/src/tools/pages.ts +20 -41
- package/src/tools/records.ts +15 -36
- package/src/tools/search.ts +7 -22
- package/src/tools/service-accounts.ts +47 -63
- package/src/tools/smart-queries.ts +8 -29
- package/src/tools/structures.ts +12 -50
- package/src/tools/validation.ts +21 -27
- package/src/tools/webhook-subscriptions.ts +363 -0
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
{
|
package/src/tools/structures.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
{
|