@mcp-consultant-tools/powerplatform-customization 20.0.0 → 25.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.js CHANGED
@@ -5,6 +5,7 @@ import { pathToFileURL } from 'node:url';
5
5
  import { realpathSync } from 'node:fs';
6
6
  import { createMcpServer, createEnvLoader } from '@mcp-consultant-tools/core';
7
7
  import { PowerPlatformService } from './PowerPlatformService.js';
8
+ import { initializePublisherPrefix } from './utils/publisherConfig.js';
8
9
  const POWERPLATFORM_DEFAULT_SOLUTION = process.env.POWERPLATFORM_DEFAULT_SOLUTION || "";
9
10
  /**
10
11
  * Register powerplatform-customization tools with an MCP server
@@ -12,30 +13,22 @@ const POWERPLATFORM_DEFAULT_SOLUTION = process.env.POWERPLATFORM_DEFAULT_SOLUTIO
12
13
  * @param service - Optional pre-initialized PowerPlatformService (for testing)
13
14
  */
14
15
  export function registerPowerplatformCustomizationTools(server, service) {
15
- // Check if customization is enabled
16
- const customizationEnabled = process.env.POWERPLATFORM_ENABLE_CUSTOMIZATION === 'true';
17
- if (!customizationEnabled) {
18
- throw new Error('powerplatform-customization tools are disabled. Set POWERPLATFORM_ENABLE_CUSTOMIZATION=true to enable.');
19
- }
20
16
  let ppService = service || null;
21
- // Check if customization is enabled
22
- function checkCustomizationEnabled() {
23
- if (process.env.POWERPLATFORM_ENABLE_CUSTOMIZATION !== 'true') {
24
- throw new Error('Customization operations are disabled. Set POWERPLATFORM_ENABLE_CUSTOMIZATION=true to enable.');
25
- }
26
- }
27
17
  function getPowerPlatformService() {
28
18
  if (!ppService) {
29
19
  const requiredVars = [
30
20
  'POWERPLATFORM_URL',
31
21
  'POWERPLATFORM_CLIENT_ID',
32
22
  'POWERPLATFORM_CLIENT_SECRET',
33
- 'POWERPLATFORM_TENANT_ID'
23
+ 'POWERPLATFORM_TENANT_ID',
24
+ 'PUBLISHER_PREFIX'
34
25
  ];
35
26
  const missing = requiredVars.filter(v => !process.env[v]);
36
27
  if (missing.length > 0) {
37
28
  throw new Error(`Missing required PowerPlatform configuration: ${missing.join(', ')}`);
38
29
  }
30
+ // Initialize publisher prefix for validation
31
+ initializePublisherPrefix();
39
32
  const config = {
40
33
  organizationUrl: process.env.POWERPLATFORM_URL,
41
34
  clientId: process.env.POWERPLATFORM_CLIENT_ID,
@@ -135,7 +128,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
135
128
  };
136
129
  }
137
130
  });
138
- server.tool("create-entity", "Create a new custom entity (table) in Dynamics 365 / PowerPlatform. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
131
+ server.tool("create-entity", "Create a new custom entity (table) in Dynamics 365 / PowerPlatform.", {
139
132
  schemaName: z.string().describe("The schema name of the entity (e.g., 'sic_application')"),
140
133
  displayName: z.string().describe("The display name of the entity (e.g., 'Application')"),
141
134
  pluralDisplayName: z.string().describe("The plural display name (e.g., 'Applications')"),
@@ -150,7 +143,6 @@ export function registerPowerplatformCustomizationTools(server, service) {
150
143
  solutionUniqueName: z.string().optional().describe("Solution to add entity to (optional, uses POWERPLATFORM_DEFAULT_SOLUTION if not specified)")
151
144
  }, async (params) => {
152
145
  try {
153
- checkCustomizationEnabled();
154
146
  const service = getPowerPlatformService();
155
147
  // Construct entity definition
156
148
  const entityDefinition = {
@@ -256,7 +248,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
256
248
  };
257
249
  }
258
250
  });
259
- server.tool("update-entity", "Update an existing custom entity. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
251
+ server.tool("update-entity", "Update an existing custom entity.", {
260
252
  metadataId: z.string().describe("The MetadataId of the entity (GUID)"),
261
253
  displayName: z.string().optional().describe("New display name"),
262
254
  pluralDisplayName: z.string().optional().describe("New plural display name"),
@@ -266,7 +258,6 @@ export function registerPowerplatformCustomizationTools(server, service) {
266
258
  solutionUniqueName: z.string().optional().describe("Solution context")
267
259
  }, async (params) => {
268
260
  try {
269
- checkCustomizationEnabled();
270
261
  const service = getPowerPlatformService();
271
262
  const updates = {};
272
263
  if (params.displayName) {
@@ -301,13 +292,12 @@ export function registerPowerplatformCustomizationTools(server, service) {
301
292
  return { content: [{ type: "text", text: `Failed to update entity: ${error.message}` }], isError: true };
302
293
  }
303
294
  });
304
- server.tool("update-entity-icon", "Update entity icon using Fluent UI System Icons from Microsoft's official icon library. Creates a web resource and sets it as the entity icon. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
295
+ server.tool("update-entity-icon", "Update entity icon using Fluent UI System Icons from Microsoft's official icon library. Creates a web resource and sets it as the entity icon.", {
305
296
  entityLogicalName: z.string().describe("The logical name of the entity (e.g., 'sic_strikeaction')"),
306
297
  iconFileName: z.string().describe("Fluent UI icon file name (e.g., 'people_community_24_filled.svg'). Browse icons at: https://github.com/microsoft/fluentui-system-icons"),
307
298
  solutionUniqueName: z.string().optional().describe("Solution to add the web resource to (optional, uses POWERPLATFORM_DEFAULT_SOLUTION if not specified)")
308
299
  }, async (params) => {
309
300
  try {
310
- checkCustomizationEnabled();
311
301
  const service = getPowerPlatformService();
312
302
  const result = await service.updateEntityIcon(params.entityLogicalName, params.iconFileName, params.solutionUniqueName);
313
303
  const message = `✅ Successfully updated entity icon
@@ -336,11 +326,10 @@ export function registerPowerplatformCustomizationTools(server, service) {
336
326
  };
337
327
  }
338
328
  });
339
- server.tool("delete-entity", "Delete a custom entity. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
329
+ server.tool("delete-entity", "Delete a custom entity.", {
340
330
  metadataId: z.string().describe("The MetadataId of the entity to delete (GUID)")
341
331
  }, async ({ metadataId }) => {
342
332
  try {
343
- checkCustomizationEnabled();
344
333
  const service = getPowerPlatformService();
345
334
  await service.deleteEntity(metadataId);
346
335
  return {
@@ -352,7 +341,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
352
341
  return { content: [{ type: "text", text: `Failed to delete entity: ${error.message}` }], isError: true };
353
342
  }
354
343
  });
355
- server.tool("create-attribute", "Create a new attribute (column) on a Dynamics 365 entity. Supports most attribute types. CRITICAL LIMITATIONS: (1) Local option sets are NOT SUPPORTED - all Picklist/MultiSelectPicklist attributes MUST use global option sets. Provide 'optionSetOptions' to auto-create a new global option set, or 'globalOptionSetName' to reference existing. (2) Customer-type attributes (polymorphic lookups) CANNOT be created via SDK - use a standard Lookup to Account or Contact instead, or create manually via Power Apps maker portal. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
344
+ server.tool("create-attribute", "Create a new attribute (column) on a Dynamics 365 entity. Supports most attribute types. CRITICAL LIMITATIONS: (1) Local option sets are NOT SUPPORTED - all Picklist/MultiSelectPicklist attributes MUST use global option sets. Provide 'optionSetOptions' to auto-create a new global option set, or 'globalOptionSetName' to reference existing. (2) Customer-type attributes (polymorphic lookups) CANNOT be created via SDK - use a standard Lookup to Account or Contact instead, or create manually via Power Apps maker portal.", {
356
345
  entityLogicalName: z.string().describe("The logical name of the entity"),
357
346
  attributeType: z.enum([
358
347
  "String", "Memo", "Integer", "Decimal", "Money", "DateTime",
@@ -391,7 +380,6 @@ export function registerPowerplatformCustomizationTools(server, service) {
391
380
  solutionUniqueName: z.string().optional().describe("Solution to add attribute to")
392
381
  }, async (params) => {
393
382
  try {
394
- checkCustomizationEnabled();
395
383
  const service = getPowerPlatformService();
396
384
  // Validate Customer attribute type early with helpful error
397
385
  if (params.attributeType === "Customer") {
@@ -804,7 +792,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
804
792
  };
805
793
  }
806
794
  });
807
- server.tool("update-attribute", "Update an existing attribute on an entity. Supports converting String attributes to AutoNumber by setting autoNumberFormat. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
795
+ server.tool("update-attribute", "Update an existing attribute on an entity. Supports converting String attributes to AutoNumber by setting autoNumberFormat.", {
808
796
  entityLogicalName: z.string().describe("Entity logical name"),
809
797
  attributeLogicalName: z.string().describe("Attribute logical name"),
810
798
  displayName: z.string().optional().describe("New display name"),
@@ -818,7 +806,6 @@ export function registerPowerplatformCustomizationTools(server, service) {
818
806
  solutionUniqueName: z.string().optional().describe("Solution context")
819
807
  }, async (params) => {
820
808
  try {
821
- checkCustomizationEnabled();
822
809
  const service = getPowerPlatformService();
823
810
  const updates = {};
824
811
  if (params.displayName) {
@@ -872,12 +859,11 @@ export function registerPowerplatformCustomizationTools(server, service) {
872
859
  return { content: [{ type: "text", text: `Failed to update attribute: ${error.message}` }], isError: true };
873
860
  }
874
861
  });
875
- server.tool("delete-attribute", "Delete an attribute from an entity. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
862
+ server.tool("delete-attribute", "Delete an attribute from an entity.", {
876
863
  entityLogicalName: z.string().describe("Entity logical name"),
877
864
  attributeMetadataId: z.string().describe("Attribute MetadataId (GUID)")
878
865
  }, async ({ entityLogicalName, attributeMetadataId }) => {
879
866
  try {
880
- checkCustomizationEnabled();
881
867
  const service = getPowerPlatformService();
882
868
  await service.deleteAttribute(entityLogicalName, attributeMetadataId);
883
869
  return {
@@ -889,7 +875,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
889
875
  return { content: [{ type: "text", text: `Failed to delete attribute: ${error.message}` }], isError: true };
890
876
  }
891
877
  });
892
- server.tool("create-one-to-many-relationship", "Create a one-to-many relationship between two entities. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
878
+ server.tool("create-one-to-many-relationship", "Create a one-to-many relationship between two entities.", {
893
879
  referencedEntity: z.string().describe("The 'one' side entity (parent)"),
894
880
  referencingEntity: z.string().describe("The 'many' side entity (child)"),
895
881
  schemaName: z.string().describe("Relationship schema name (e.g., 'sic_account_application')"),
@@ -898,7 +884,6 @@ export function registerPowerplatformCustomizationTools(server, service) {
898
884
  solutionUniqueName: z.string().optional().describe("Solution to add to")
899
885
  }, async (params) => {
900
886
  try {
901
- checkCustomizationEnabled();
902
887
  const service = getPowerPlatformService();
903
888
  const relationshipDefinition = {
904
889
  "@odata.type": "Microsoft.Dynamics.CRM.OneToManyRelationshipMetadata",
@@ -925,7 +910,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
925
910
  return { content: [{ type: "text", text: `Failed to create relationship: ${error.message}` }], isError: true };
926
911
  }
927
912
  });
928
- server.tool("create-many-to-many-relationship", "Create a many-to-many relationship between two entities. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
913
+ server.tool("create-many-to-many-relationship", "Create a many-to-many relationship between two entities.", {
929
914
  entity1: z.string().describe("First entity logical name"),
930
915
  entity2: z.string().describe("Second entity logical name"),
931
916
  schemaName: z.string().describe("Relationship schema name (e.g., 'sic_account_contact')"),
@@ -933,7 +918,6 @@ export function registerPowerplatformCustomizationTools(server, service) {
933
918
  solutionUniqueName: z.string().optional().describe("Solution to add to")
934
919
  }, async (params) => {
935
920
  try {
936
- checkCustomizationEnabled();
937
921
  const service = getPowerPlatformService();
938
922
  const relationshipDefinition = {
939
923
  "@odata.type": "Microsoft.Dynamics.CRM.ManyToManyRelationshipMetadata",
@@ -953,11 +937,10 @@ export function registerPowerplatformCustomizationTools(server, service) {
953
937
  return { content: [{ type: "text", text: `Failed to create relationship: ${error.message}` }], isError: true };
954
938
  }
955
939
  });
956
- server.tool("delete-relationship", "Delete a relationship. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
940
+ server.tool("delete-relationship", "Delete a relationship.", {
957
941
  metadataId: z.string().describe("Relationship MetadataId (GUID)")
958
942
  }, async ({ metadataId }) => {
959
943
  try {
960
- checkCustomizationEnabled();
961
944
  const service = getPowerPlatformService();
962
945
  await service.deleteRelationship(metadataId);
963
946
  return {
@@ -969,13 +952,12 @@ export function registerPowerplatformCustomizationTools(server, service) {
969
952
  return { content: [{ type: "text", text: `Failed to delete relationship: ${error.message}` }], isError: true };
970
953
  }
971
954
  });
972
- server.tool("update-relationship", "Update relationship labels. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
955
+ server.tool("update-relationship", "Update relationship labels.", {
973
956
  metadataId: z.string().describe("Relationship MetadataId (GUID)"),
974
957
  referencedEntityNavigationPropertyName: z.string().optional().describe("Navigation property name"),
975
958
  referencingEntityNavigationPropertyName: z.string().optional().describe("Navigation property name")
976
959
  }, async (params) => {
977
960
  try {
978
- checkCustomizationEnabled();
979
961
  const service = getPowerPlatformService();
980
962
  const updates = {};
981
963
  if (params.referencedEntityNavigationPropertyName)
@@ -992,7 +974,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
992
974
  return { content: [{ type: "text", text: `Failed to update relationship: ${error.message}` }], isError: true };
993
975
  }
994
976
  });
995
- server.tool("create-global-optionset-attribute", "Create a picklist attribute using an existing global option set. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
977
+ server.tool("create-global-optionset-attribute", "Create a picklist attribute using an existing global option set.", {
996
978
  entityLogicalName: z.string().describe("Entity logical name"),
997
979
  schemaName: z.string().describe("Attribute schema name"),
998
980
  displayName: z.string().describe("Attribute display name"),
@@ -1002,7 +984,6 @@ export function registerPowerplatformCustomizationTools(server, service) {
1002
984
  solutionUniqueName: z.string().optional().describe("Solution to add to")
1003
985
  }, async (params) => {
1004
986
  try {
1005
- checkCustomizationEnabled();
1006
987
  const service = getPowerPlatformService();
1007
988
  // Look up the global option set to get its MetadataId
1008
989
  const globalOptionSet = await service.getGlobalOptionSet(params.globalOptionSetName);
@@ -1032,9 +1013,8 @@ export function registerPowerplatformCustomizationTools(server, service) {
1032
1013
  return { content: [{ type: "text", text: `Failed to create global option set attribute: ${error.message}` }], isError: true };
1033
1014
  }
1034
1015
  });
1035
- server.tool("publish-customizations", "Publish all pending customizations in Dynamics 365. This makes all unpublished changes active. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {}, async () => {
1016
+ server.tool("publish-customizations", "Publish all pending customizations in Dynamics 365. This makes all unpublished changes active.", {}, async () => {
1036
1017
  try {
1037
- checkCustomizationEnabled();
1038
1018
  const service = getPowerPlatformService();
1039
1019
  await service.publishAllCustomizations();
1040
1020
  return {
@@ -1059,14 +1039,13 @@ export function registerPowerplatformCustomizationTools(server, service) {
1059
1039
  };
1060
1040
  }
1061
1041
  });
1062
- server.tool("update-global-optionset", "Update a global option set in Dynamics 365. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1042
+ server.tool("update-global-optionset", "Update a global option set in Dynamics 365.", {
1063
1043
  metadataId: z.string().describe("The MetadataId of the option set"),
1064
1044
  displayName: z.string().optional().describe("New display name"),
1065
1045
  description: z.string().optional().describe("New description"),
1066
1046
  solutionUniqueName: z.string().optional().describe("Solution to add to (optional, uses POWERPLATFORM_DEFAULT_SOLUTION if not provided)")
1067
1047
  }, async ({ metadataId, displayName, description, solutionUniqueName }) => {
1068
1048
  try {
1069
- checkCustomizationEnabled();
1070
1049
  const service = getPowerPlatformService();
1071
1050
  const updates = { '@odata.type': 'Microsoft.Dynamics.CRM.OptionSetMetadata' };
1072
1051
  if (displayName) {
@@ -1099,14 +1078,13 @@ export function registerPowerplatformCustomizationTools(server, service) {
1099
1078
  };
1100
1079
  }
1101
1080
  });
1102
- server.tool("add-optionset-value", "Add a new value to a global option set in Dynamics 365. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1081
+ server.tool("add-optionset-value", "Add a new value to a global option set in Dynamics 365.", {
1103
1082
  optionSetName: z.string().describe("The name of the option set"),
1104
1083
  value: z.number().describe("The numeric value (should start with publisher prefix, e.g., 15743xxxx)"),
1105
1084
  label: z.string().describe("The display label for the value"),
1106
1085
  solutionUniqueName: z.string().optional().describe("Solution to add to")
1107
1086
  }, async ({ optionSetName, value, label, solutionUniqueName }) => {
1108
1087
  try {
1109
- checkCustomizationEnabled();
1110
1088
  const service = getPowerPlatformService();
1111
1089
  const solution = solutionUniqueName || POWERPLATFORM_DEFAULT_SOLUTION;
1112
1090
  await service.addOptionSetValue(optionSetName, value, label, solution);
@@ -1130,14 +1108,13 @@ export function registerPowerplatformCustomizationTools(server, service) {
1130
1108
  };
1131
1109
  }
1132
1110
  });
1133
- server.tool("update-optionset-value", "Update an existing value in a global option set. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1111
+ server.tool("update-optionset-value", "Update an existing value in a global option set.", {
1134
1112
  optionSetName: z.string().describe("The name of the option set"),
1135
1113
  value: z.number().describe("The numeric value to update"),
1136
1114
  label: z.string().describe("The new display label"),
1137
1115
  solutionUniqueName: z.string().optional().describe("Solution to add to")
1138
1116
  }, async ({ optionSetName, value, label, solutionUniqueName }) => {
1139
1117
  try {
1140
- checkCustomizationEnabled();
1141
1118
  const service = getPowerPlatformService();
1142
1119
  const solution = solutionUniqueName || POWERPLATFORM_DEFAULT_SOLUTION;
1143
1120
  await service.updateOptionSetValue(optionSetName, value, label, solution);
@@ -1161,12 +1138,11 @@ export function registerPowerplatformCustomizationTools(server, service) {
1161
1138
  };
1162
1139
  }
1163
1140
  });
1164
- server.tool("delete-optionset-value", "Delete a value from a global option set. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1141
+ server.tool("delete-optionset-value", "Delete a value from a global option set.", {
1165
1142
  optionSetName: z.string().describe("The name of the option set"),
1166
1143
  value: z.number().describe("The numeric value to delete")
1167
1144
  }, async ({ optionSetName, value }) => {
1168
1145
  try {
1169
- checkCustomizationEnabled();
1170
1146
  const service = getPowerPlatformService();
1171
1147
  await service.deleteOptionSetValue(optionSetName, value);
1172
1148
  return {
@@ -1187,13 +1163,12 @@ export function registerPowerplatformCustomizationTools(server, service) {
1187
1163
  };
1188
1164
  }
1189
1165
  });
1190
- server.tool("reorder-optionset-values", "Reorder the values in a global option set. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1166
+ server.tool("reorder-optionset-values", "Reorder the values in a global option set.", {
1191
1167
  optionSetName: z.string().describe("The name of the option set"),
1192
1168
  values: z.array(z.number()).describe("Array of values in the desired order"),
1193
1169
  solutionUniqueName: z.string().optional().describe("Solution to add to")
1194
1170
  }, async ({ optionSetName, values, solutionUniqueName }) => {
1195
1171
  try {
1196
- checkCustomizationEnabled();
1197
1172
  const service = getPowerPlatformService();
1198
1173
  const solution = solutionUniqueName || POWERPLATFORM_DEFAULT_SOLUTION;
1199
1174
  await service.reorderOptionSetValues(optionSetName, values, solution);
@@ -1215,7 +1190,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
1215
1190
  };
1216
1191
  }
1217
1192
  });
1218
- server.tool("create-form", "Create a new form (Main, QuickCreate, QuickView, Card) for an entity. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1193
+ server.tool("create-form", "Create a new form (Main, QuickCreate, QuickView, Card) for an entity.", {
1219
1194
  name: z.string().describe("Form name"),
1220
1195
  entityLogicalName: z.string().describe("Entity logical name"),
1221
1196
  formType: z.enum(["Main", "QuickCreate", "QuickView", "Card"]).describe("Form type"),
@@ -1224,7 +1199,6 @@ export function registerPowerplatformCustomizationTools(server, service) {
1224
1199
  solutionUniqueName: z.string().optional().describe("Solution to add to")
1225
1200
  }, async ({ name, entityLogicalName, formType, formXml, description, solutionUniqueName }) => {
1226
1201
  try {
1227
- checkCustomizationEnabled();
1228
1202
  const service = getPowerPlatformService();
1229
1203
  const typeMap = { Main: 2, QuickCreate: 7, QuickView: 8, Card: 10 };
1230
1204
  const form = {
@@ -1255,7 +1229,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
1255
1229
  };
1256
1230
  }
1257
1231
  });
1258
- server.tool("update-form", "Update an existing form. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1232
+ server.tool("update-form", "Update an existing form.", {
1259
1233
  formId: z.string().describe("Form ID (GUID)"),
1260
1234
  name: z.string().optional().describe("New form name"),
1261
1235
  formXml: z.string().optional().describe("New form XML definition"),
@@ -1263,7 +1237,6 @@ export function registerPowerplatformCustomizationTools(server, service) {
1263
1237
  solutionUniqueName: z.string().optional().describe("Solution to add to")
1264
1238
  }, async ({ formId, name, formXml, description, solutionUniqueName }) => {
1265
1239
  try {
1266
- checkCustomizationEnabled();
1267
1240
  const service = getPowerPlatformService();
1268
1241
  const updates = {};
1269
1242
  if (name)
@@ -1292,11 +1265,10 @@ export function registerPowerplatformCustomizationTools(server, service) {
1292
1265
  };
1293
1266
  }
1294
1267
  });
1295
- server.tool("delete-form", "Delete a form. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1268
+ server.tool("delete-form", "Delete a form.", {
1296
1269
  formId: z.string().describe("Form ID (GUID)")
1297
1270
  }, async ({ formId }) => {
1298
1271
  try {
1299
- checkCustomizationEnabled();
1300
1272
  const service = getPowerPlatformService();
1301
1273
  await service.deleteForm(formId);
1302
1274
  return {
@@ -1317,11 +1289,10 @@ export function registerPowerplatformCustomizationTools(server, service) {
1317
1289
  };
1318
1290
  }
1319
1291
  });
1320
- server.tool("activate-form", "Activate a form. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1292
+ server.tool("activate-form", "Activate a form.", {
1321
1293
  formId: z.string().describe("Form ID (GUID)")
1322
1294
  }, async ({ formId }) => {
1323
1295
  try {
1324
- checkCustomizationEnabled();
1325
1296
  const service = getPowerPlatformService();
1326
1297
  await service.activateForm(formId);
1327
1298
  return {
@@ -1342,11 +1313,10 @@ export function registerPowerplatformCustomizationTools(server, service) {
1342
1313
  };
1343
1314
  }
1344
1315
  });
1345
- server.tool("deactivate-form", "Deactivate a form. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1316
+ server.tool("deactivate-form", "Deactivate a form.", {
1346
1317
  formId: z.string().describe("Form ID (GUID)")
1347
1318
  }, async ({ formId }) => {
1348
1319
  try {
1349
- checkCustomizationEnabled();
1350
1320
  const service = getPowerPlatformService();
1351
1321
  await service.deactivateForm(formId);
1352
1322
  return {
@@ -1367,7 +1337,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
1367
1337
  };
1368
1338
  }
1369
1339
  });
1370
- server.tool("create-view", "Create a new view for an entity using FetchXML. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1340
+ server.tool("create-view", "Create a new view for an entity using FetchXML.", {
1371
1341
  name: z.string().describe("View name"),
1372
1342
  entityLogicalName: z.string().describe("Entity logical name"),
1373
1343
  fetchXml: z.string().describe("FetchXML query"),
@@ -1378,7 +1348,6 @@ export function registerPowerplatformCustomizationTools(server, service) {
1378
1348
  solutionUniqueName: z.string().optional().describe("Solution to add to")
1379
1349
  }, async ({ name, entityLogicalName, fetchXml, layoutXml, queryType, isDefault, description, solutionUniqueName }) => {
1380
1350
  try {
1381
- checkCustomizationEnabled();
1382
1351
  const service = getPowerPlatformService();
1383
1352
  const view = {
1384
1353
  name,
@@ -1410,7 +1379,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
1410
1379
  };
1411
1380
  }
1412
1381
  });
1413
- server.tool("update-view", "Update an existing view. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1382
+ server.tool("update-view", "Update an existing view.", {
1414
1383
  viewId: z.string().describe("View ID (GUID)"),
1415
1384
  name: z.string().optional().describe("New view name"),
1416
1385
  fetchXml: z.string().optional().describe("New FetchXML query"),
@@ -1420,7 +1389,6 @@ export function registerPowerplatformCustomizationTools(server, service) {
1420
1389
  solutionUniqueName: z.string().optional().describe("Solution to add to")
1421
1390
  }, async ({ viewId, name, fetchXml, layoutXml, isDefault, description, solutionUniqueName }) => {
1422
1391
  try {
1423
- checkCustomizationEnabled();
1424
1392
  const service = getPowerPlatformService();
1425
1393
  const updates = {};
1426
1394
  if (name)
@@ -1453,11 +1421,10 @@ export function registerPowerplatformCustomizationTools(server, service) {
1453
1421
  };
1454
1422
  }
1455
1423
  });
1456
- server.tool("delete-view", "Delete a view. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1424
+ server.tool("delete-view", "Delete a view.", {
1457
1425
  viewId: z.string().describe("View ID (GUID)")
1458
1426
  }, async ({ viewId }) => {
1459
1427
  try {
1460
- checkCustomizationEnabled();
1461
1428
  const service = getPowerPlatformService();
1462
1429
  await service.deleteView(viewId);
1463
1430
  return {
@@ -1478,11 +1445,10 @@ export function registerPowerplatformCustomizationTools(server, service) {
1478
1445
  };
1479
1446
  }
1480
1447
  });
1481
- server.tool("set-default-view", "Set a view as the default view for its entity. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1448
+ server.tool("set-default-view", "Set a view as the default view for its entity.", {
1482
1449
  viewId: z.string().describe("View ID (GUID)")
1483
1450
  }, async ({ viewId }) => {
1484
1451
  try {
1485
- checkCustomizationEnabled();
1486
1452
  const service = getPowerPlatformService();
1487
1453
  await service.setDefaultView(viewId);
1488
1454
  return {
@@ -1503,7 +1469,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
1503
1469
  };
1504
1470
  }
1505
1471
  });
1506
- server.tool("create-web-resource", "Create a new web resource (JavaScript, CSS, HTML, Image, etc.). Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1472
+ server.tool("create-web-resource", "Create a new web resource (JavaScript, CSS, HTML, Image, etc.).", {
1507
1473
  name: z.string().describe("Web resource name (must include prefix, e.g., 'prefix_/scripts/file.js')"),
1508
1474
  displayName: z.string().describe("Display name"),
1509
1475
  webResourceType: z.number().describe("Web resource type: 1=HTML, 2=CSS, 3=JavaScript, 4=XML, 5=PNG, 6=JPG, 7=GIF, 8=XAP, 9=XSL, 10=ICO"),
@@ -1512,7 +1478,6 @@ export function registerPowerplatformCustomizationTools(server, service) {
1512
1478
  solutionUniqueName: z.string().optional().describe("Solution to add to")
1513
1479
  }, async ({ name, displayName, webResourceType, content, description, solutionUniqueName }) => {
1514
1480
  try {
1515
- checkCustomizationEnabled();
1516
1481
  const service = getPowerPlatformService();
1517
1482
  const webResource = {
1518
1483
  name,
@@ -1542,7 +1507,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
1542
1507
  };
1543
1508
  }
1544
1509
  });
1545
- server.tool("update-web-resource", "Update an existing web resource. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1510
+ server.tool("update-web-resource", "Update an existing web resource.", {
1546
1511
  webResourceId: z.string().describe("Web resource ID (GUID)"),
1547
1512
  displayName: z.string().optional().describe("Display name"),
1548
1513
  content: z.string().optional().describe("Base64-encoded content"),
@@ -1550,7 +1515,6 @@ export function registerPowerplatformCustomizationTools(server, service) {
1550
1515
  solutionUniqueName: z.string().optional().describe("Solution context")
1551
1516
  }, async ({ webResourceId, displayName, content, description, solutionUniqueName }) => {
1552
1517
  try {
1553
- checkCustomizationEnabled();
1554
1518
  const service = getPowerPlatformService();
1555
1519
  const updates = {};
1556
1520
  if (displayName)
@@ -1579,11 +1543,10 @@ export function registerPowerplatformCustomizationTools(server, service) {
1579
1543
  };
1580
1544
  }
1581
1545
  });
1582
- server.tool("delete-web-resource", "Delete a web resource. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1546
+ server.tool("delete-web-resource", "Delete a web resource.", {
1583
1547
  webResourceId: z.string().describe("Web resource ID (GUID)")
1584
1548
  }, async ({ webResourceId }) => {
1585
1549
  try {
1586
- checkCustomizationEnabled();
1587
1550
  const service = getPowerPlatformService();
1588
1551
  await service.deleteWebResource(webResourceId);
1589
1552
  return {
@@ -1604,7 +1567,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
1604
1567
  };
1605
1568
  }
1606
1569
  });
1607
- server.tool("create-publisher", "Create a new solution publisher. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1570
+ server.tool("create-publisher", "Create a new solution publisher.", {
1608
1571
  uniqueName: z.string().describe("Publisher unique name"),
1609
1572
  friendlyName: z.string().describe("Publisher display name"),
1610
1573
  customizationPrefix: z.string().describe("Customization prefix (e.g., 'new')"),
@@ -1612,7 +1575,6 @@ export function registerPowerplatformCustomizationTools(server, service) {
1612
1575
  description: z.string().optional().describe("Publisher description")
1613
1576
  }, async ({ uniqueName, friendlyName, customizationPrefix, customizationOptionValuePrefix, description }) => {
1614
1577
  try {
1615
- checkCustomizationEnabled();
1616
1578
  const service = getPowerPlatformService();
1617
1579
  const publisher = {
1618
1580
  uniquename: uniqueName,
@@ -1643,7 +1605,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
1643
1605
  };
1644
1606
  }
1645
1607
  });
1646
- server.tool("create-solution", "Create a new solution. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1608
+ server.tool("create-solution", "Create a new solution.", {
1647
1609
  uniqueName: z.string().describe("Solution unique name"),
1648
1610
  friendlyName: z.string().describe("Solution display name"),
1649
1611
  version: z.string().describe("Solution version (e.g., '1.0.0.0')"),
@@ -1651,7 +1613,6 @@ export function registerPowerplatformCustomizationTools(server, service) {
1651
1613
  description: z.string().optional().describe("Solution description")
1652
1614
  }, async ({ uniqueName, friendlyName, version, publisherId, description }) => {
1653
1615
  try {
1654
- checkCustomizationEnabled();
1655
1616
  const service = getPowerPlatformService();
1656
1617
  const solution = {
1657
1618
  uniquename: uniqueName,
@@ -1681,7 +1642,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
1681
1642
  };
1682
1643
  }
1683
1644
  });
1684
- server.tool("add-solution-component", "Add a component to a solution. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1645
+ server.tool("add-solution-component", "Add a component to a solution.", {
1685
1646
  solutionUniqueName: z.string().describe("Solution unique name"),
1686
1647
  componentId: z.string().describe("Component ID (GUID or MetadataId)"),
1687
1648
  componentType: z.number().describe("Component type: 1=Entity, 2=Attribute, 9=OptionSet, 24=Form, 26=SavedQuery, 29=Workflow, 60=SystemForm, 61=WebResource"),
@@ -1689,7 +1650,6 @@ export function registerPowerplatformCustomizationTools(server, service) {
1689
1650
  includedComponentSettingsValues: z.string().optional().describe("Component settings values")
1690
1651
  }, async ({ solutionUniqueName, componentId, componentType, addRequiredComponents, includedComponentSettingsValues }) => {
1691
1652
  try {
1692
- checkCustomizationEnabled();
1693
1653
  const service = getPowerPlatformService();
1694
1654
  await service.addComponentToSolution(solutionUniqueName, componentId, componentType, addRequiredComponents ?? true, includedComponentSettingsValues);
1695
1655
  return {
@@ -1709,13 +1669,12 @@ export function registerPowerplatformCustomizationTools(server, service) {
1709
1669
  };
1710
1670
  }
1711
1671
  });
1712
- server.tool("remove-solution-component", "Remove a component from a solution. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1672
+ server.tool("remove-solution-component", "Remove a component from a solution.", {
1713
1673
  solutionUniqueName: z.string().describe("Solution unique name"),
1714
1674
  componentId: z.string().describe("Component ID (GUID or MetadataId)"),
1715
1675
  componentType: z.number().describe("Component type: 1=Entity, 2=Attribute, 9=OptionSet, 24=Form, 26=SavedQuery, 29=Workflow, 60=SystemForm, 61=WebResource")
1716
1676
  }, async ({ solutionUniqueName, componentId, componentType }) => {
1717
1677
  try {
1718
- checkCustomizationEnabled();
1719
1678
  const service = getPowerPlatformService();
1720
1679
  await service.removeComponentFromSolution(solutionUniqueName, componentId, componentType);
1721
1680
  return {
@@ -1735,12 +1694,11 @@ export function registerPowerplatformCustomizationTools(server, service) {
1735
1694
  };
1736
1695
  }
1737
1696
  });
1738
- server.tool("export-solution", "Export a solution as a zip file. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1697
+ server.tool("export-solution", "Export a solution as a zip file.", {
1739
1698
  solutionName: z.string().describe("Solution unique name"),
1740
1699
  managed: z.boolean().optional().describe("Export as managed solution (default: false)")
1741
1700
  }, async ({ solutionName, managed }) => {
1742
1701
  try {
1743
- checkCustomizationEnabled();
1744
1702
  const service = getPowerPlatformService();
1745
1703
  const result = await service.exportSolution(solutionName, managed ?? false);
1746
1704
  return {
@@ -1761,13 +1719,12 @@ export function registerPowerplatformCustomizationTools(server, service) {
1761
1719
  };
1762
1720
  }
1763
1721
  });
1764
- server.tool("import-solution", "Import a solution from a base64-encoded zip file. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1722
+ server.tool("import-solution", "Import a solution from a base64-encoded zip file.", {
1765
1723
  customizationFile: z.string().describe("Base64-encoded solution zip file"),
1766
1724
  publishWorkflows: z.boolean().optional().describe("Publish workflows after import (default: true)"),
1767
1725
  overwriteUnmanagedCustomizations: z.boolean().optional().describe("Overwrite unmanaged customizations (default: false)")
1768
1726
  }, async ({ customizationFile, publishWorkflows, overwriteUnmanagedCustomizations }) => {
1769
1727
  try {
1770
- checkCustomizationEnabled();
1771
1728
  const service = getPowerPlatformService();
1772
1729
  const result = await service.importSolution(customizationFile, publishWorkflows ?? true, overwriteUnmanagedCustomizations ?? false);
1773
1730
  return {
@@ -1789,11 +1746,10 @@ export function registerPowerplatformCustomizationTools(server, service) {
1789
1746
  };
1790
1747
  }
1791
1748
  });
1792
- server.tool("publish-entity", "Publish all customizations for a specific entity. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1749
+ server.tool("publish-entity", "Publish all customizations for a specific entity.", {
1793
1750
  entityLogicalName: z.string().describe("Entity logical name to publish")
1794
1751
  }, async ({ entityLogicalName }) => {
1795
1752
  try {
1796
- checkCustomizationEnabled();
1797
1753
  const service = getPowerPlatformService();
1798
1754
  await service.publishEntity(entityLogicalName);
1799
1755
  return {
@@ -1817,7 +1773,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
1817
1773
  // ============================================================
1818
1774
  // PLUGIN DEPLOYMENT TOOLS
1819
1775
  // ============================================================
1820
- server.tool("create-plugin-assembly", "Upload a compiled plugin DLL to Dynamics 365 from local file system. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1776
+ server.tool("create-plugin-assembly", "Upload a compiled plugin DLL to Dynamics 365 from local file system.", {
1821
1777
  assemblyPath: z.string().describe("Local file path to compiled DLL (e.g., C:\\Dev\\MyPlugin\\bin\\Release\\net462\\MyPlugin.dll)"),
1822
1778
  assemblyName: z.string().describe("Friendly name for the assembly (e.g., MyPlugin)"),
1823
1779
  version: z.string().optional().describe("Version string (auto-extracted if omitted, e.g., '1.0.0.0')"),
@@ -1826,7 +1782,6 @@ export function registerPowerplatformCustomizationTools(server, service) {
1826
1782
  solutionUniqueName: z.string().optional().describe("Solution to add assembly to"),
1827
1783
  }, async ({ assemblyPath, assemblyName, version, isolationMode, description, solutionUniqueName }) => {
1828
1784
  try {
1829
- checkCustomizationEnabled();
1830
1785
  const service = getPowerPlatformService();
1831
1786
  // Read DLL file from file system (Windows or WSL compatible)
1832
1787
  const fs = await import('fs/promises');
@@ -1869,14 +1824,13 @@ export function registerPowerplatformCustomizationTools(server, service) {
1869
1824
  };
1870
1825
  }
1871
1826
  });
1872
- server.tool("update-plugin-assembly", "Update an existing plugin assembly with new compiled DLL. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1827
+ server.tool("update-plugin-assembly", "Update an existing plugin assembly with new compiled DLL.", {
1873
1828
  assemblyId: z.string().describe("Assembly ID (GUID)"),
1874
1829
  assemblyPath: z.string().describe("Local file path to new compiled DLL"),
1875
1830
  version: z.string().optional().describe("Version string (auto-extracted if omitted)"),
1876
1831
  solutionUniqueName: z.string().optional().describe("Solution context"),
1877
1832
  }, async ({ assemblyId, assemblyPath, version, solutionUniqueName }) => {
1878
1833
  try {
1879
- checkCustomizationEnabled();
1880
1834
  const service = getPowerPlatformService();
1881
1835
  // Read new DLL
1882
1836
  const fs = await import('fs/promises');
@@ -1906,7 +1860,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
1906
1860
  };
1907
1861
  }
1908
1862
  });
1909
- server.tool("register-plugin-step", "Register a plugin step on an SDK message. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1863
+ server.tool("register-plugin-step", "Register a plugin step on an SDK message.", {
1910
1864
  assemblyName: z.string().describe("Assembly name (e.g., MyPlugin)"),
1911
1865
  pluginTypeName: z.string().describe("Full type name (e.g., MyOrg.Plugins.ContactPlugin)"),
1912
1866
  stepName: z.string().describe("Friendly step name (e.g., 'Contact: Update - Post-Operation')"),
@@ -1920,7 +1874,6 @@ export function registerPowerplatformCustomizationTools(server, service) {
1920
1874
  solutionUniqueName: z.string().optional(),
1921
1875
  }, async (params) => {
1922
1876
  try {
1923
- checkCustomizationEnabled();
1924
1877
  const service = getPowerPlatformService();
1925
1878
  // Resolve plugin type ID by typename
1926
1879
  const pluginTypeId = await service.queryPluginTypeByTypename(params.pluginTypeName);
@@ -1966,7 +1919,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
1966
1919
  };
1967
1920
  }
1968
1921
  });
1969
- server.tool("register-plugin-image", "Add a pre/post image to a plugin step for accessing entity data. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1922
+ server.tool("register-plugin-image", "Add a pre/post image to a plugin step for accessing entity data.", {
1970
1923
  stepId: z.string().describe("Plugin step ID (from register-plugin-step)"),
1971
1924
  imageName: z.string().describe("Image name (e.g., 'PreImage', 'PostImage')"),
1972
1925
  imageType: z.enum(['PreImage', 'PostImage', 'Both']).describe("Image type"),
@@ -1975,7 +1928,6 @@ export function registerPowerplatformCustomizationTools(server, service) {
1975
1928
  messagePropertyName: z.string().optional().describe("Message property (default: 'Target')"),
1976
1929
  }, async (params) => {
1977
1930
  try {
1978
- checkCustomizationEnabled();
1979
1931
  const service = getPowerPlatformService();
1980
1932
  const imageTypeMap = { PreImage: 0, PostImage: 1, Both: 2 };
1981
1933
  const result = await service.registerPluginImage({
@@ -2005,7 +1957,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
2005
1957
  };
2006
1958
  }
2007
1959
  });
2008
- server.tool("deploy-plugin-complete", "End-to-end plugin deployment: upload DLL, register steps, configure images, and publish. Requires POWERPLATFORM_ENABLE_CUSTOMIZATION=true.", {
1960
+ server.tool("deploy-plugin-complete", "End-to-end plugin deployment: upload DLL, register steps, configure images, and publish.", {
2009
1961
  assemblyPath: z.string().describe("Local DLL file path"),
2010
1962
  assemblyName: z.string().describe("Assembly name"),
2011
1963
  stepConfigurations: z.array(z.object({
@@ -2032,7 +1984,6 @@ export function registerPowerplatformCustomizationTools(server, service) {
2032
1984
  replaceExisting: z.boolean().optional().describe("Update existing assembly vs. create new"),
2033
1985
  }, async (params) => {
2034
1986
  try {
2035
- checkCustomizationEnabled();
2036
1987
  const service = getPowerPlatformService();
2037
1988
  const summary = {
2038
1989
  phases: {