mcp-creatio 0.3.8 → 0.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.
Files changed (96) hide show
  1. package/Agent.md +4 -1
  2. package/README.md +131 -113
  3. package/dist/creatio/engines/admin-operation/admin-operation-engine.d.ts +13 -0
  4. package/dist/creatio/engines/admin-operation/admin-operation-engine.d.ts.map +1 -0
  5. package/dist/creatio/engines/admin-operation/admin-operation-engine.js +27 -0
  6. package/dist/creatio/engines/admin-operation/admin-operation-engine.js.map +1 -0
  7. package/dist/creatio/engines/configuration/configuration-engine.d.ts +10 -0
  8. package/dist/creatio/engines/configuration/configuration-engine.d.ts.map +1 -0
  9. package/dist/creatio/engines/configuration/configuration-engine.js +18 -0
  10. package/dist/creatio/engines/configuration/configuration-engine.js.map +1 -0
  11. package/dist/creatio/engines/engine-manager.d.ts +13 -1
  12. package/dist/creatio/engines/engine-manager.d.ts.map +1 -1
  13. package/dist/creatio/engines/engine-manager.js +17 -0
  14. package/dist/creatio/engines/engine-manager.js.map +1 -1
  15. package/dist/creatio/engines/engine-registry.d.ts +3 -0
  16. package/dist/creatio/engines/engine-registry.d.ts.map +1 -1
  17. package/dist/creatio/engines/engine-registry.js +3 -0
  18. package/dist/creatio/engines/engine-registry.js.map +1 -1
  19. package/dist/creatio/engines/feature/feature-engine.d.ts +10 -0
  20. package/dist/creatio/engines/feature/feature-engine.d.ts.map +1 -0
  21. package/dist/creatio/engines/feature/feature-engine.js +18 -0
  22. package/dist/creatio/engines/feature/feature-engine.js.map +1 -0
  23. package/dist/creatio/engines/index.d.ts +3 -0
  24. package/dist/creatio/engines/index.d.ts.map +1 -1
  25. package/dist/creatio/engines/index.js +3 -0
  26. package/dist/creatio/engines/index.js.map +1 -1
  27. package/dist/creatio/provider-context.d.ts +4 -1
  28. package/dist/creatio/provider-context.d.ts.map +1 -1
  29. package/dist/creatio/providers/admin-operation-provider.d.ts +27 -0
  30. package/dist/creatio/providers/admin-operation-provider.d.ts.map +1 -0
  31. package/dist/creatio/providers/admin-operation-provider.js +3 -0
  32. package/dist/creatio/providers/admin-operation-provider.js.map +1 -0
  33. package/dist/creatio/providers/configuration-provider.d.ts +19 -0
  34. package/dist/creatio/providers/configuration-provider.d.ts.map +1 -0
  35. package/dist/creatio/providers/configuration-provider.js +3 -0
  36. package/dist/creatio/providers/configuration-provider.js.map +1 -0
  37. package/dist/creatio/providers/feature-provider.d.ts +10 -0
  38. package/dist/creatio/providers/feature-provider.d.ts.map +1 -0
  39. package/dist/creatio/providers/feature-provider.js +3 -0
  40. package/dist/creatio/providers/feature-provider.js.map +1 -0
  41. package/dist/creatio/providers/index.d.ts +3 -0
  42. package/dist/creatio/providers/index.d.ts.map +1 -1
  43. package/dist/creatio/providers/index.js +3 -0
  44. package/dist/creatio/providers/index.js.map +1 -1
  45. package/dist/creatio/services/admin-operation-service-provider.d.ts +15 -0
  46. package/dist/creatio/services/admin-operation-service-provider.d.ts.map +1 -0
  47. package/dist/creatio/services/admin-operation-service-provider.js +69 -0
  48. package/dist/creatio/services/admin-operation-service-provider.js.map +1 -0
  49. package/dist/creatio/services/configuration-service-provider.d.ts +14 -0
  50. package/dist/creatio/services/configuration-service-provider.d.ts.map +1 -0
  51. package/dist/creatio/services/configuration-service-provider.js +90 -0
  52. package/dist/creatio/services/configuration-service-provider.js.map +1 -0
  53. package/dist/creatio/services/creatio-service-context.d.ts +4 -1
  54. package/dist/creatio/services/creatio-service-context.d.ts.map +1 -1
  55. package/dist/creatio/services/creatio-service-context.js +9 -0
  56. package/dist/creatio/services/creatio-service-context.js.map +1 -1
  57. package/dist/creatio/services/feature-service-provider.d.ts +10 -0
  58. package/dist/creatio/services/feature-service-provider.d.ts.map +1 -0
  59. package/dist/creatio/services/feature-service-provider.js +43 -0
  60. package/dist/creatio/services/feature-service-provider.js.map +1 -0
  61. package/dist/creatio/services/index.d.ts +3 -0
  62. package/dist/creatio/services/index.d.ts.map +1 -1
  63. package/dist/creatio/services/index.js +3 -0
  64. package/dist/creatio/services/index.js.map +1 -1
  65. package/dist/server/mcp/prompts-data.d.ts +58 -0
  66. package/dist/server/mcp/prompts-data.d.ts.map +1 -1
  67. package/dist/server/mcp/prompts-data.js +391 -1
  68. package/dist/server/mcp/prompts-data.js.map +1 -1
  69. package/dist/server/mcp/server.d.ts.map +1 -1
  70. package/dist/server/mcp/server.js +69 -0
  71. package/dist/server/mcp/server.js.map +1 -1
  72. package/dist/server/mcp/tools-data.d.ts +63 -0
  73. package/dist/server/mcp/tools-data.d.ts.map +1 -1
  74. package/dist/server/mcp/tools-data.js +110 -5
  75. package/dist/server/mcp/tools-data.js.map +1 -1
  76. package/package.json +23 -10
  77. package/src/creatio/engines/admin-operation/admin-operation-engine.ts +44 -0
  78. package/src/creatio/engines/configuration/configuration-engine.ts +26 -0
  79. package/src/creatio/engines/engine-manager.ts +56 -1
  80. package/src/creatio/engines/engine-registry.ts +3 -0
  81. package/src/creatio/engines/feature/feature-engine.ts +20 -0
  82. package/src/creatio/engines/index.ts +3 -0
  83. package/src/creatio/provider-context.ts +12 -1
  84. package/src/creatio/providers/admin-operation-provider.ts +34 -0
  85. package/src/creatio/providers/configuration-provider.ts +22 -0
  86. package/src/creatio/providers/feature-provider.ts +10 -0
  87. package/src/creatio/providers/index.ts +3 -0
  88. package/src/creatio/services/admin-operation-service-provider.ts +115 -0
  89. package/src/creatio/services/configuration-service-provider.ts +127 -0
  90. package/src/creatio/services/creatio-service-context.ts +18 -1
  91. package/src/creatio/services/feature-service-provider.ts +60 -0
  92. package/src/creatio/services/index.ts +3 -0
  93. package/src/server/mcp/prompts-data.ts +396 -0
  94. package/src/server/mcp/server.ts +111 -0
  95. package/src/server/mcp/tools-data.ts +160 -4
  96. package/ecosystem.config.json +0 -17
@@ -887,10 +887,406 @@ export const SYS_SETTINGS_PROMPT = {
887
887
  }),
888
888
  };
889
889
 
890
+ const FEATURE_TOGGLE_GUIDE = `
891
+ # 🚦 Feature Toggling Guide for Creatio
892
+
893
+ ## 🧭 Quick Map
894
+
895
+ Creatio feature toggles are stored in TWO database-backed entities, both reachable via OData:
896
+
897
+ | Entity | What it represents | When to use |
898
+ |--------------------------|--------------------------------------------------------------------------|--------------------------------------|
899
+ | \`Feature\` | Catalog row for a feature (Code, Name, Description, DefaultState) | Read/create/update/delete the toggle |
900
+ | \`AdminUnitFeatureState\` | Per-user/role override (FeatureId, SysAdminUnitId, FeatureState) | Override a feature for one principal |
901
+
902
+ There is **NO** dedicated feature CRUD tool — use the existing \`read\`, \`create\`, \`update\`, \`delete\` tools on the entity sets above. The only feature-specific tool is \`refresh-feature-cache\`.
903
+
904
+ > ℹ️ The Freedom UI in Creatio shows a virtual section called *AppFeature* that adds a couple of computed columns (\`Source\`, \`StateForCurrentUser\`). Those virtual entities are **not** exposed through OData — always use the persisted \`Feature\` and \`AdminUnitFeatureState\` tables from automation.
905
+
906
+ ---
907
+
908
+ ## 📋 Feature Columns
909
+
910
+ | Column | Type | Notes |
911
+ |-----------------|----------|------------------------------------------------------------------------|
912
+ | \`Id\` | Guid | Primary key |
913
+ | \`Code\` | string | Feature code. Must match \`^[a-zA-Z]+[a-zA-Z0-9-_.]*$\` |
914
+ | \`Name\` | string | Display name (commonly equal to \`Code\`) |
915
+ | \`Description\` | string | Optional description |
916
+ | \`DefaultState\` | Int32 | **0 = disabled, 1 = enabled**. NOT a boolean — always send integers. |
917
+ | \`ProcessListeners\` | Int32 | Internal flag — leave it as the default value |
918
+ | \`CreatedOn\` / \`ModifiedOn\` | DateTime | Audit fields |
919
+
920
+ ---
921
+
922
+ ## 📋 AdminUnitFeatureState Columns
923
+
924
+ | Column | Type | Notes |
925
+ |-------------------|--------|------------------------------------------------------------------|
926
+ | \`Id\` | Guid | Primary key |
927
+ | \`FeatureId\` | Guid | FK → \`Feature.Id\` |
928
+ | \`SysAdminUnitId\` | Guid | FK → \`SysAdminUnit.Id\` (the user or role) |
929
+ | \`FeatureState\` | Int32 | **0 = disabled, 1 = enabled** for that admin unit |
930
+ | \`ProcessListeners\`| Int32 | Internal flag — leave default |
931
+
932
+ \`SysAdminUnitId\` is the **SysAdminUnit.Id** of the principal (not its ContactId). Look it up explicitly when you only know a user/role name.
933
+
934
+ ---
935
+
936
+ ## 🛠️ Common Workflows
937
+
938
+ ### 1. List features
939
+
940
+ \`\`\`json
941
+ {
942
+ "entity": "Feature",
943
+ "select": ["Id", "Code", "Name", "Description", "DefaultState"],
944
+ "top": 200,
945
+ "orderBy": "Code asc"
946
+ }
947
+ \`\`\`
948
+
949
+ ### 2. Look up one feature by code
950
+
951
+ \`\`\`json
952
+ {
953
+ "entity": "Feature",
954
+ "filters": { "all": [ { "field": "Code", "op": "eq", "value": "MyFeature" } ] },
955
+ "select": ["Id", "Code", "DefaultState"],
956
+ "top": 1
957
+ }
958
+ \`\`\`
959
+
960
+ ### 3. Enable or disable a feature globally (change default state)
961
+
962
+ \`\`\`json
963
+ {
964
+ "entity": "Feature",
965
+ "id": "<feature-guid>",
966
+ "data": { "DefaultState": 1 }
967
+ }
968
+ \`\`\`
969
+
970
+ Use \`1\` to enable, \`0\` to disable. After the update, run \`refresh-feature-cache\` with the same feature \`Code\` so the new value is visible to every connected user.
971
+
972
+ ### 4. Create a new feature
973
+
974
+ \`\`\`json
975
+ {
976
+ "entity": "Feature",
977
+ "data": {
978
+ "Code": "MyNewFeature",
979
+ "Name": "MyNewFeature",
980
+ "Description": "Enables the new dashboard",
981
+ "DefaultState": 0
982
+ }
983
+ }
984
+ \`\`\`
985
+
986
+ Then refresh the cache.
987
+
988
+ ### 5. Override a feature for a specific user or role
989
+
990
+ First resolve the principal's \`SysAdminUnit.Id\`:
991
+
992
+ \`\`\`json
993
+ {
994
+ "entity": "SysAdminUnit",
995
+ "filters": { "all": [ { "field": "Name", "op": "eq", "value": "Supervisor" } ] },
996
+ "select": ["Id", "Name", "SysAdminUnitTypeValue"],
997
+ "top": 1
998
+ }
999
+ \`\`\`
1000
+
1001
+ Then create or update the override:
1002
+
1003
+ \`\`\`json
1004
+ {
1005
+ "entity": "AdminUnitFeatureState",
1006
+ "data": {
1007
+ "FeatureId": "<feature-guid>",
1008
+ "SysAdminUnitId": "<sysadminunit-guid>",
1009
+ "FeatureState": 1
1010
+ }
1011
+ }
1012
+ \`\`\`
1013
+
1014
+ If an override row already exists for the same \`(FeatureId, SysAdminUnitId)\` pair, query it first and \`update\` it instead of creating a duplicate. Refresh the cache afterwards.
1015
+
1016
+ ### 6. Inspect overrides for a feature
1017
+
1018
+ \`\`\`json
1019
+ {
1020
+ "entity": "AdminUnitFeatureState",
1021
+ "filters": { "all": [ { "field": "FeatureId", "op": "eq", "value": "<feature-guid>" } ] },
1022
+ "select": ["Id", "FeatureId", "SysAdminUnitId", "FeatureState"]
1023
+ }
1024
+ \`\`\`
1025
+
1026
+ ### 7. Remove an override
1027
+
1028
+ \`\`\`json
1029
+ { "entity": "AdminUnitFeatureState", "id": "<override-guid>" }
1030
+ \`\`\`
1031
+
1032
+ ### 8. Delete a feature
1033
+
1034
+ \`\`\`json
1035
+ { "entity": "Feature", "id": "<feature-guid>" }
1036
+ \`\`\`
1037
+
1038
+ Deletes the catalog row. Existing \`AdminUnitFeatureState\` rows tied to that feature should be removed first (query them with the filter from step 6) — Creatio will reject the delete if dependent rows remain.
1039
+
1040
+ ---
1041
+
1042
+ ## 🔁 When to refresh the cache
1043
+
1044
+ Call the \`refresh-feature-cache\` tool **after** any write that changes feature state:
1045
+ - Updated \`Feature.DefaultState\` → refresh with that feature's \`Code\`.
1046
+ - Created, updated, or deleted an \`AdminUnitFeatureState\` row → refresh with the affected feature's \`Code\`.
1047
+ - If you do not know (or don't have) the code, call \`refresh-feature-cache\` with no arguments to clear the cache for every feature.
1048
+
1049
+ Reads alone do **not** require a refresh.
1050
+
1051
+ ---
1052
+
1053
+ ## ❌ Common Mistakes
1054
+
1055
+ - ❌ Sending \`true\`/\`false\` for \`DefaultState\` or \`FeatureState\` — both columns are **Int32** (0 / 1).
1056
+ - ❌ Using \`AppFeature\` / \`AppFeatureState\` over OData — those are virtual UI-only entities. Use \`Feature\` / \`AdminUnitFeatureState\`.
1057
+ - ❌ Confusing \`SysAdminUnit.Id\` with \`ContactId\` — overrides use \`SysAdminUnit.Id\`.
1058
+ - ❌ Forgetting to call \`refresh-feature-cache\` after writes (other users keep seeing the old state).
1059
+ - ❌ Creating a duplicate \`AdminUnitFeatureState\` for the same \`(FeatureId, SysAdminUnitId)\` pair instead of updating the existing one.
1060
+ - ❌ Using a \`Code\` that doesn't match \`^[a-zA-Z]+[a-zA-Z0-9-_.]*$\` — the platform validator rejects it.
1061
+ - ❌ Trying to manage features that are NOT in the \`Feature\` table — Creatio OData v4 does not expose virtual entities (\`AppFeature\` / \`AppFeatureState\`). Features defined only in \`web.config\` or via non-DB providers are invisible to MCP until a backing row exists in \`Feature\`.
1062
+
1063
+ ---
1064
+
1065
+ ## ✅ Final Checklist
1066
+
1067
+ Before reporting a feature change as done:
1068
+ - [ ] Used \`Feature\` for the catalog and \`AdminUnitFeatureState\` for per-user/role overrides.
1069
+ - [ ] Sent state values as integers (0 / 1), not booleans.
1070
+ - [ ] Resolved the principal via \`SysAdminUnit\` (Id, not ContactId).
1071
+ - [ ] Called \`refresh-feature-cache\` (with \`featureCode\` when possible) after every write.
1072
+ `.trim();
1073
+
1074
+ export const FEATURE_TOGGLE_PROMPT = {
1075
+ name: 'feature-toggle-guide',
1076
+ title: 'Creatio Feature Toggle Guide',
1077
+ description:
1078
+ 'How to read, create, update and delete feature toggles via the AppFeature / AppFeatureState OData entities, and when to call refresh-feature-cache',
1079
+ argsSchema: {},
1080
+ callback: () => ({
1081
+ messages: [
1082
+ {
1083
+ role: 'user' as const,
1084
+ content: { type: 'text' as const, text: FEATURE_TOGGLE_GUIDE },
1085
+ },
1086
+ ],
1087
+ }),
1088
+ };
1089
+
1090
+ const ADMIN_OPERATION_GUIDE = `
1091
+ # 🛡️ Creatio System Operations (SysAdminOperation) Guide
1092
+
1093
+ ## 🧭 Quick Map
1094
+
1095
+ Creatio system operations are admin-level permission flags that gate features such as \`CanUseODataService\`, \`CanManageAdministration\`, \`CanChangeAdminOperationGrantee\`, etc. They live in two database tables:
1096
+
1097
+ | Table | Holds | OData reachable? |
1098
+ |-----------------------------|----------------------------------------------------------------|------------------|
1099
+ | \`SysAdminOperation\` | The operation definition: Name, Code, Description | Read ✅ / Write ❌ |
1100
+ | \`SysAdminOperationGrantee\` | Per-admin-unit grants (FK to operation + SysAdminUnit + allow) | Read ✅ / Write ❌ |
1101
+
1102
+ Modification of both tables is blocked through OData v4 (\`DataServiceRestrictedModifySchemas\` in \`Web.config\`). All writes go through Creatio's dedicated **\`/0/rest/RightsService/\`** endpoints, wrapped by these MCP tools:
1103
+
1104
+ | Need | Tool |
1105
+ |------------------------------------------|---------------------------------------|
1106
+ | Read catalog / grant rows | Standard \`read\` on the two entities |
1107
+ | Create or rename an operation | \`upsert-admin-operation\` |
1108
+ | Delete operation(s) | \`delete-admin-operation\` |
1109
+ | Grant or revoke for users/roles | \`set-admin-operation-grantee\` |
1110
+ | Remove a specific grant row by Id | \`delete-admin-operation-grantee\` |
1111
+
1112
+ ⚠️ Do NOT attempt \`create\` / \`update\` / \`delete\` on \`SysAdminOperation\` or \`SysAdminOperationGrantee\` through the generic OData tools — Creatio rejects those writes.
1113
+
1114
+ ---
1115
+
1116
+ ## 📋 SysAdminOperation Columns
1117
+
1118
+ | Column | Type | Notes |
1119
+ |-----------------|----------|--------------------------------------------------------------------|
1120
+ | \`Id\` | Guid | Primary key |
1121
+ | \`Code\` | string | Operation code, e.g., \`CanUseODataService\`. Conventionally PascalCase. |
1122
+ | \`Name\` | string | Display name |
1123
+ | \`Description\` | string | Optional description |
1124
+
1125
+ ## 📋 SysAdminOperationGrantee Columns
1126
+
1127
+ | Column | Type | Notes |
1128
+ |-------------------------|---------|-----------------------------------------------------------------------------|
1129
+ | \`Id\` | Guid | Primary key |
1130
+ | \`SysAdminOperationId\` | Guid | FK to \`SysAdminOperation\` |
1131
+ | \`SysAdminUnitId\` | Guid | FK to \`SysAdminUnit\` (use SysAdminUnit.Id, NOT ContactId) |
1132
+ | \`CanExecute\` | bool | \`true\` = allow, \`false\` = deny |
1133
+ | \`Position\` | Int32 | Order within conflicting rules; lower wins for the same admin unit |
1134
+
1135
+ ---
1136
+
1137
+ ## 🛠️ Common Workflows
1138
+
1139
+ ### 1. List system operations
1140
+
1141
+ \`\`\`json
1142
+ {
1143
+ "entity": "SysAdminOperation",
1144
+ "select": ["Id", "Code", "Name", "Description"],
1145
+ "top": 200,
1146
+ "orderBy": "Code asc"
1147
+ }
1148
+ \`\`\`
1149
+
1150
+ ### 2. Look up an operation by code
1151
+
1152
+ \`\`\`json
1153
+ {
1154
+ "entity": "SysAdminOperation",
1155
+ "filters": { "all": [ { "field": "Code", "op": "eq", "value": "CanUseODataService" } ] },
1156
+ "select": ["Id", "Code", "Name", "Description"],
1157
+ "top": 1
1158
+ }
1159
+ \`\`\`
1160
+
1161
+ ### 3. Create a new system operation
1162
+
1163
+ Call \`upsert-admin-operation\` without an \`id\`:
1164
+
1165
+ \`\`\`json
1166
+ {
1167
+ "name": "Can do MCP test",
1168
+ "code": "CanDoMcpTest",
1169
+ "description": "Demo operation managed via MCP"
1170
+ }
1171
+ \`\`\`
1172
+
1173
+ The response includes the generated \`id\`. Capture it for the grant step.
1174
+
1175
+ ### 4. Rename / re-describe an existing operation
1176
+
1177
+ Call \`upsert-admin-operation\` with the existing \`id\`:
1178
+
1179
+ \`\`\`json
1180
+ {
1181
+ "id": "<operation-guid>",
1182
+ "name": "Can do MCP test (renamed)",
1183
+ "code": "CanDoMcpTest",
1184
+ "description": "Updated description"
1185
+ }
1186
+ \`\`\`
1187
+
1188
+ Code is required even when unchanged.
1189
+
1190
+ ### 5. Grant the operation to a user or role
1191
+
1192
+ Resolve the SysAdminUnit first:
1193
+
1194
+ \`\`\`json
1195
+ {
1196
+ "entity": "SysAdminUnit",
1197
+ "filters": { "all": [ { "field": "Name", "op": "eq", "value": "Supervisor" } ] },
1198
+ "select": ["Id", "Name", "SysAdminUnitTypeValue"],
1199
+ "top": 1
1200
+ }
1201
+ \`\`\`
1202
+
1203
+ Then call \`set-admin-operation-grantee\`:
1204
+
1205
+ \`\`\`json
1206
+ {
1207
+ "adminOperationId": "<operation-guid>",
1208
+ "adminUnitIds": ["<sysadminunit-guid-1>", "<sysadminunit-guid-2>"],
1209
+ "canExecute": true
1210
+ }
1211
+ \`\`\`
1212
+
1213
+ Use \`canExecute: false\` to deny instead of allow. The service upserts the grantee rows internally — repeated calls for the same pair update the existing row instead of duplicating it.
1214
+
1215
+ ### 6. Inspect current grants for an operation
1216
+
1217
+ ⚠️ **Filter via the navigation property, not the raw FK column.** Creatio OData v4 rejects direct \`SysAdminOperationId eq <guid>\` / \`SysAdminUnitId eq <guid>\` filters on this entity with HTTP 500. Use \`SysAdminOperation/Id\` and \`SysAdminUnit/Id\` instead:
1218
+
1219
+ \`\`\`json
1220
+ {
1221
+ "entity": "SysAdminOperationGrantee",
1222
+ "filters": { "all": [ { "field": "SysAdminOperation/Id", "op": "eq", "value": "<operation-guid>" } ] },
1223
+ "select": ["Id", "SysAdminOperationId", "SysAdminUnitId", "CanExecute", "Position"]
1224
+ }
1225
+ \`\`\`
1226
+
1227
+ ### 7. Remove a specific grant row
1228
+
1229
+ Use the row Id from step 6:
1230
+
1231
+ \`\`\`json
1232
+ { "ids": ["<grantee-guid>"] }
1233
+ \`\`\`
1234
+
1235
+ Call \`delete-admin-operation-grantee\`. Prefer toggling \`canExecute\` via \`set-admin-operation-grantee\` if the goal is to flip allow ↔ deny rather than fully remove the rule.
1236
+
1237
+ ### 8. Delete an operation entirely
1238
+
1239
+ \`\`\`json
1240
+ { "ids": ["<operation-guid-1>", "<operation-guid-2>"] }
1241
+ \`\`\`
1242
+
1243
+ Call \`delete-admin-operation\`. RightsService cascades cleanup of related grantee rows.
1244
+
1245
+ ---
1246
+
1247
+ ## ❌ Common Mistakes
1248
+
1249
+ - ❌ Trying to write to \`SysAdminOperation\` or \`SysAdminOperationGrantee\` via the generic OData \`create\` / \`update\` / \`delete\` tools — these tables are in \`DataServiceRestrictedModifySchemas\`.
1250
+ - ❌ Passing the all-zero GUID as \`id\` to \`upsert-admin-operation\` to "create" — RightsService rejects it. Omit \`id\` and let the tool generate a fresh one.
1251
+ - ❌ Using \`ContactId\` instead of \`SysAdminUnit.Id\` for grantees.
1252
+ - ❌ Forgetting to confirm with \`read\` that the change landed — RightsService responses return \`success: true\` only when the underlying entity actually saved.
1253
+ - ❌ Granting the operation to many units one by one — pass the full \`adminUnitIds\` array in a single call.
1254
+ - ❌ Filtering \`SysAdminOperationGrantee\` by the raw \`SysAdminOperationId\` / \`SysAdminUnitId\` columns — Creatio OData returns HTTP 500 for those. Use the navigation property syntax \`SysAdminOperation/Id\` / \`SysAdminUnit/Id\`.
1255
+
1256
+ ---
1257
+
1258
+ ## ✅ Final Checklist
1259
+
1260
+ Before reporting a system-operation change as done:
1261
+ - [ ] Used \`SysAdminOperation\` / \`SysAdminOperationGrantee\` only for reading.
1262
+ - [ ] Used \`upsert-admin-operation\` / \`delete-admin-operation\` for catalog writes.
1263
+ - [ ] Used \`set-admin-operation-grantee\` / \`delete-admin-operation-grantee\` for grants.
1264
+ - [ ] Resolved each principal through \`SysAdminUnit\` (Id, not ContactId).
1265
+ - [ ] Re-read the affected rows to confirm the change landed.
1266
+ `.trim();
1267
+
1268
+ export const ADMIN_OPERATION_PROMPT = {
1269
+ name: 'admin-operation-guide',
1270
+ title: 'Creatio System Operations (SysAdminOperation) Guide',
1271
+ description:
1272
+ 'How to manage SysAdminOperation and SysAdminOperationGrantee via the dedicated RightsService tools (upsert/delete operation, set/delete grantee), with reads still routed through the standard OData read tool',
1273
+ argsSchema: {},
1274
+ callback: () => ({
1275
+ messages: [
1276
+ {
1277
+ role: 'user' as const,
1278
+ content: { type: 'text' as const, text: ADMIN_OPERATION_GUIDE },
1279
+ },
1280
+ ],
1281
+ }),
1282
+ };
1283
+
890
1284
  export const ALL_PROMPTS = [
891
1285
  CREATE_ACTIVITY_PROMPT,
892
1286
  DATETIME_PROMPT,
893
1287
  CONTACTID_PROMPT,
894
1288
  TAGGING_PROMPT,
895
1289
  SYS_SETTINGS_PROMPT,
1290
+ FEATURE_TOGGLE_PROMPT,
1291
+ ADMIN_OPERATION_PROMPT,
896
1292
  ] as const;
@@ -12,10 +12,16 @@ import { NAME, VERSION } from '../../version';
12
12
  import { buildFilterFromStructured } from './filters';
13
13
  import { ALL_PROMPTS } from './prompts-data';
14
14
  import {
15
+ callConfigurationServiceDescriptor,
16
+ callConfigurationServiceInput,
15
17
  createDescriptor,
16
18
  createInput,
17
19
  createSysSettingDescriptor,
18
20
  createSysSettingInput,
21
+ deleteAdminOperationDescriptor,
22
+ deleteAdminOperationGranteeDescriptor,
23
+ deleteAdminOperationGranteeInput,
24
+ deleteAdminOperationInput,
19
25
  deleteDescriptor,
20
26
  deleteInput,
21
27
  describeEntityDescriptor,
@@ -30,12 +36,18 @@ import {
30
36
  querySysSettingsInput,
31
37
  readDescriptor,
32
38
  readInput,
39
+ refreshFeatureCacheDescriptor,
40
+ refreshFeatureCacheInput,
41
+ setAdminOperationGranteeDescriptor,
42
+ setAdminOperationGranteeInput,
33
43
  setSysSettingsValueDescriptor,
34
44
  setSysSettingsValueInput,
35
45
  updateDescriptor,
36
46
  updateInput,
37
47
  updateSysSettingDefinitionDescriptor,
38
48
  updateSysSettingDefinitionInput,
49
+ upsertAdminOperationDescriptor,
50
+ upsertAdminOperationInput,
39
51
  } from './tools-data';
40
52
 
41
53
  type ToolHandler = (payload: any) => Promise<any>;
@@ -216,6 +228,9 @@ export class Server {
216
228
  );
217
229
  if (!this._readonly) {
218
230
  const process = this._engines.process;
231
+ const feature = this._engines.feature;
232
+ const adminOperation = this._engines.adminOperation;
233
+ const configuration = this._engines.configuration;
219
234
  this._registerHandlerWithDescriptor(
220
235
  'create',
221
236
  createDescriptor,
@@ -301,6 +316,102 @@ export class Server {
301
316
  };
302
317
  }),
303
318
  );
319
+ this._registerHandlerWithDescriptor(
320
+ 'refresh-feature-cache',
321
+ refreshFeatureCacheDescriptor,
322
+ withValidation(refreshFeatureCacheInput, async ({ featureCode }) => {
323
+ const result = await feature.clearFeaturesCache(featureCode);
324
+ return {
325
+ content: [
326
+ {
327
+ type: 'text',
328
+ text: JSON.stringify(result, null, 2),
329
+ },
330
+ ],
331
+ };
332
+ }),
333
+ );
334
+ this._registerHandlerWithDescriptor(
335
+ 'upsert-admin-operation',
336
+ upsertAdminOperationDescriptor,
337
+ withValidation(upsertAdminOperationInput, async ({ id, name, code, description }) => {
338
+ const result = await adminOperation.upsertAdminOperation({
339
+ ...(id !== undefined ? { id } : {}),
340
+ name,
341
+ code,
342
+ ...(description !== undefined ? { description } : {}),
343
+ });
344
+ return {
345
+ content: [
346
+ { type: 'text', text: JSON.stringify(result, null, 2) },
347
+ ],
348
+ };
349
+ }),
350
+ );
351
+ this._registerHandlerWithDescriptor(
352
+ 'delete-admin-operation',
353
+ deleteAdminOperationDescriptor,
354
+ withValidation(deleteAdminOperationInput, async ({ ids }) => {
355
+ const result = await adminOperation.deleteAdminOperation(ids);
356
+ return {
357
+ content: [
358
+ { type: 'text', text: JSON.stringify(result, null, 2) },
359
+ ],
360
+ };
361
+ }),
362
+ );
363
+ this._registerHandlerWithDescriptor(
364
+ 'set-admin-operation-grantee',
365
+ setAdminOperationGranteeDescriptor,
366
+ withValidation(
367
+ setAdminOperationGranteeInput,
368
+ async ({ adminOperationId, adminUnitIds, canExecute }) => {
369
+ const result = await adminOperation.setAdminOperationGrantee({
370
+ adminOperationId,
371
+ adminUnitIds,
372
+ canExecute,
373
+ });
374
+ return {
375
+ content: [
376
+ { type: 'text', text: JSON.stringify(result, null, 2) },
377
+ ],
378
+ };
379
+ },
380
+ ),
381
+ );
382
+ this._registerHandlerWithDescriptor(
383
+ 'delete-admin-operation-grantee',
384
+ deleteAdminOperationGranteeDescriptor,
385
+ withValidation(deleteAdminOperationGranteeInput, async ({ ids }) => {
386
+ const result = await adminOperation.deleteAdminOperationGrantee(ids);
387
+ return {
388
+ content: [
389
+ { type: 'text', text: JSON.stringify(result, null, 2) },
390
+ ],
391
+ };
392
+ }),
393
+ );
394
+ this._registerHandlerWithDescriptor(
395
+ 'call-configuration-service',
396
+ callConfigurationServiceDescriptor,
397
+ withValidation(
398
+ callConfigurationServiceInput,
399
+ async ({ service, method, httpMethod, body, query }) => {
400
+ const result = await configuration.call({
401
+ service,
402
+ method,
403
+ httpMethod,
404
+ ...(body !== undefined ? { body } : {}),
405
+ ...(query !== undefined ? { query } : {}),
406
+ });
407
+ return {
408
+ content: [
409
+ { type: 'text', text: JSON.stringify(result, null, 2) },
410
+ ],
411
+ };
412
+ },
413
+ ),
414
+ );
304
415
  }
305
416
  }
306
417