@mcp-consultant-tools/powerplatform-customization 25.0.0-beta.5 → 26.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/build/index.js CHANGED
@@ -5,7 +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
+ import { initializePublisherPrefix } from '@mcp-consultant-tools/powerplatform-core';
9
9
  const POWERPLATFORM_DEFAULT_SOLUTION = process.env.POWERPLATFORM_DEFAULT_SOLUTION || "";
10
10
  /**
11
11
  * Register powerplatform-customization tools with an MCP server
@@ -1110,25 +1110,12 @@ export function registerPowerplatformCustomizationTools(server, service) {
1110
1110
  }, async (params) => {
1111
1111
  try {
1112
1112
  const service = getPowerPlatformService();
1113
- // Look up the global option set to get its MetadataId
1114
- const globalOptionSet = await service.getGlobalOptionSet(params.globalOptionSetName);
1115
- const metadataId = globalOptionSet.MetadataId;
1116
- const attributeDefinition = {
1117
- "@odata.type": "Microsoft.Dynamics.CRM.PicklistAttributeMetadata",
1118
- SchemaName: params.schemaName,
1119
- DisplayName: {
1120
- "@odata.type": "Microsoft.Dynamics.CRM.Label",
1121
- LocalizedLabels: [{ "@odata.type": "Microsoft.Dynamics.CRM.LocalizedLabel", Label: params.displayName, LanguageCode: 1033 }]
1122
- },
1123
- Description: {
1124
- "@odata.type": "Microsoft.Dynamics.CRM.Label",
1125
- LocalizedLabels: [{ "@odata.type": "Microsoft.Dynamics.CRM.LocalizedLabel", Label: params.description || "", LanguageCode: 1033 }]
1126
- },
1127
- RequiredLevel: { Value: params.requiredLevel || "None", CanBeChanged: true },
1128
- "GlobalOptionSet@odata.bind": `/GlobalOptionSetDefinitions(${metadataId})`
1129
- };
1130
1113
  const solution = params.solutionUniqueName || POWERPLATFORM_DEFAULT_SOLUTION;
1131
- const result = await service.createGlobalOptionSetAttribute(params.entityLogicalName, attributeDefinition, solution);
1114
+ const result = await service.createGlobalOptionSetAttribute(params.entityLogicalName, params.schemaName, params.displayName, params.globalOptionSetName, {
1115
+ description: params.description,
1116
+ requiredLevel: params.requiredLevel,
1117
+ solutionUniqueName: solution
1118
+ });
1132
1119
  return {
1133
1120
  content: [{ type: "text", text: `✅ Successfully created global option set attribute '${params.schemaName}' using '${params.globalOptionSetName}'\n\n⚠️ IMPORTANT: You must publish this customization using the 'publish-customizations' tool before it becomes active.` }]
1134
1121
  };
@@ -1325,16 +1312,8 @@ export function registerPowerplatformCustomizationTools(server, service) {
1325
1312
  }, async ({ name, entityLogicalName, formType, formXml, description, solutionUniqueName }) => {
1326
1313
  try {
1327
1314
  const service = getPowerPlatformService();
1328
- const typeMap = { Main: 2, QuickCreate: 7, QuickView: 8, Card: 10 };
1329
- const form = {
1330
- name,
1331
- objecttypecode: entityLogicalName,
1332
- type: typeMap[formType],
1333
- formxml: formXml,
1334
- description: description || ""
1335
- };
1336
1315
  const solution = solutionUniqueName || POWERPLATFORM_DEFAULT_SOLUTION;
1337
- const result = await service.createForm(form, solution);
1316
+ const result = await service.createForm(name, entityLogicalName, formType, formXml, { description, solutionUniqueName: solution });
1338
1317
  return {
1339
1318
  content: [
1340
1319
  {
@@ -1474,17 +1453,13 @@ export function registerPowerplatformCustomizationTools(server, service) {
1474
1453
  }, async ({ name, entityLogicalName, fetchXml, layoutXml, queryType, isDefault, description, solutionUniqueName }) => {
1475
1454
  try {
1476
1455
  const service = getPowerPlatformService();
1477
- const view = {
1478
- name,
1479
- returnedtypecode: entityLogicalName,
1480
- fetchxml: fetchXml,
1481
- layoutxml: layoutXml,
1482
- querytype: queryType || 0,
1483
- isdefault: isDefault || false,
1484
- description: description || ""
1485
- };
1486
1456
  const solution = solutionUniqueName || POWERPLATFORM_DEFAULT_SOLUTION;
1487
- const result = await service.createView(view, solution);
1457
+ const result = await service.createView(name, entityLogicalName, fetchXml, layoutXml, {
1458
+ queryType: queryType || 0,
1459
+ isDefault: isDefault || false,
1460
+ description,
1461
+ solutionUniqueName: solution
1462
+ });
1488
1463
  return {
1489
1464
  content: [
1490
1465
  {
@@ -1604,15 +1579,8 @@ export function registerPowerplatformCustomizationTools(server, service) {
1604
1579
  }, async ({ name, displayName, webResourceType, content, description, solutionUniqueName }) => {
1605
1580
  try {
1606
1581
  const service = getPowerPlatformService();
1607
- const webResource = {
1608
- name,
1609
- displayname: displayName,
1610
- webresourcetype: webResourceType,
1611
- content,
1612
- description: description || ""
1613
- };
1614
1582
  const solution = solutionUniqueName || POWERPLATFORM_DEFAULT_SOLUTION;
1615
- const result = await service.createWebResource(webResource, solution);
1583
+ const result = await service.createWebResource(name, displayName, webResourceType, content, { description, solutionUniqueName: solution });
1616
1584
  return {
1617
1585
  content: [
1618
1586
  {
@@ -1701,14 +1669,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
1701
1669
  }, async ({ uniqueName, friendlyName, customizationPrefix, customizationOptionValuePrefix, description }) => {
1702
1670
  try {
1703
1671
  const service = getPowerPlatformService();
1704
- const publisher = {
1705
- uniquename: uniqueName,
1706
- friendlyname: friendlyName,
1707
- customizationprefix: customizationPrefix,
1708
- customizationoptionvalueprefix: customizationOptionValuePrefix,
1709
- description: description || ""
1710
- };
1711
- const result = await service.createPublisher(publisher);
1672
+ const result = await service.createPublisher(uniqueName, friendlyName, customizationPrefix, customizationOptionValuePrefix, description);
1712
1673
  return {
1713
1674
  content: [
1714
1675
  {
@@ -1739,14 +1700,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
1739
1700
  }, async ({ uniqueName, friendlyName, version, publisherId, description }) => {
1740
1701
  try {
1741
1702
  const service = getPowerPlatformService();
1742
- const solution = {
1743
- uniquename: uniqueName,
1744
- friendlyname: friendlyName,
1745
- version,
1746
- "publisherid@odata.bind": `/publishers(${publisherId})`,
1747
- description: description || ""
1748
- };
1749
- const result = await service.createSolution(solution);
1703
+ const result = await service.createSolution(uniqueName, friendlyName, version, publisherId, description);
1750
1704
  return {
1751
1705
  content: [
1752
1706
  {
@@ -1773,10 +1727,10 @@ export function registerPowerplatformCustomizationTools(server, service) {
1773
1727
  componentType: z.number().describe("Component type: 1=Entity, 2=Attribute, 9=OptionSet, 24=Form, 26=SavedQuery, 29=Workflow, 60=SystemForm, 61=WebResource"),
1774
1728
  addRequiredComponents: z.boolean().optional().describe("Add required components (default: true)"),
1775
1729
  includedComponentSettingsValues: z.string().optional().describe("Component settings values")
1776
- }, async ({ solutionUniqueName, componentId, componentType, addRequiredComponents, includedComponentSettingsValues }) => {
1730
+ }, async ({ solutionUniqueName, componentId, componentType, addRequiredComponents }) => {
1777
1731
  try {
1778
1732
  const service = getPowerPlatformService();
1779
- await service.addComponentToSolution(solutionUniqueName, componentId, componentType, addRequiredComponents ?? true, includedComponentSettingsValues);
1733
+ await service.addComponentToSolution(solutionUniqueName, componentId, componentType, addRequiredComponents ?? true);
1780
1734
  return {
1781
1735
  content: [
1782
1736
  {
@@ -1831,7 +1785,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
1831
1785
  {
1832
1786
  type: "text",
1833
1787
  text: `✅ Successfully exported solution '${solutionName}' as ${managed ? 'managed' : 'unmanaged'}\n\n` +
1834
- `Export File (Base64): ${result.ExportSolutionFile.substring(0, 100)}...`
1788
+ `Export File (Base64): ${(result.ExportSolutionFile || result).substring(0, 100)}...`
1835
1789
  }
1836
1790
  ]
1837
1791
  };
@@ -1851,7 +1805,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
1851
1805
  }, async ({ customizationFile, publishWorkflows, overwriteUnmanagedCustomizations }) => {
1852
1806
  try {
1853
1807
  const service = getPowerPlatformService();
1854
- const result = await service.importSolution(customizationFile, publishWorkflows ?? true, overwriteUnmanagedCustomizations ?? false);
1808
+ const result = await service.importSolution(customizationFile, overwriteUnmanagedCustomizations ?? false, publishWorkflows ?? true);
1855
1809
  return {
1856
1810
  content: [
1857
1811
  {
@@ -1937,7 +1891,7 @@ export function registerPowerplatformCustomizationTools(server, service) {
1937
1891
  `🔢 Version: ${extractedVersion}\n` +
1938
1892
  `💾 Size: ${(dllBuffer.length / 1024).toFixed(2)} KB\n` +
1939
1893
  `🔌 Plugin Types Created: ${result.pluginTypes.length}\n\n` +
1940
- `Plugin Types:\n${result.pluginTypes.map(t => ` • ${t.typeName} (${t.pluginTypeId})`).join('\n') || ' (none created yet - check System Jobs)'}`
1894
+ `Plugin Types:\n${result.pluginTypes.map((t) => ` • ${t.typeName} (${t.pluginTypeId})`).join('\n') || ' (none created yet - check System Jobs)'}`
1941
1895
  }]
1942
1896
  };
1943
1897
  }
@@ -2420,13 +2374,16 @@ export function registerPowerplatformCustomizationTools(server, service) {
2420
2374
  const service = getPowerPlatformService();
2421
2375
  const result = await service.documentAutomation(automationId, type);
2422
2376
  // Format the response with preserved line breaks in description
2377
+ const actionSummary = result.analysis.actionCount > 0
2378
+ ? `${result.analysis.actionCount} actions${result.analysis.actions.length > 0 ? ': ' + result.analysis.actions.slice(0, 5).join(', ') + (result.analysis.actionCount > 5 ? '...' : '') : ''}`
2379
+ : 'none';
2423
2380
  const responseText = `✅ Successfully documented automation
2424
2381
 
2425
2382
  **Analysis:**
2426
2383
  - Tables Modified: ${result.analysis.tablesModified.join(', ') || 'none'}
2427
2384
  - Trigger: ${result.analysis.trigger}
2428
2385
  - Trigger Fields: ${result.analysis.triggerFields.join(', ') || 'none'}
2429
- - Actions: ${result.analysis.actions.join(', ')}
2386
+ - Actions: ${actionSummary}
2430
2387
 
2431
2388
  **Description Updated:** ${result.descriptionUpdated ? 'Yes' : 'No'}
2432
2389
 
@@ -2453,7 +2410,309 @@ ${result.newDescription}`;
2453
2410
  };
2454
2411
  }
2455
2412
  });
2456
- console.error(`powerplatform-customization tools registered (${49} tools)`);
2413
+ server.tool("deactivate-workflow", "Deactivate a workflow (set to Draft state). Required before modifying classic workflow definitions.", {
2414
+ workflowId: z.string().describe("GUID of the workflow to deactivate")
2415
+ }, async ({ workflowId }) => {
2416
+ try {
2417
+ const service = getPowerPlatformService();
2418
+ const result = await service.deactivateWorkflow(workflowId);
2419
+ const responseText = `✅ Workflow deactivated successfully
2420
+
2421
+ **Workflow:** ${result.workflowName}
2422
+ **Previous State:** ${result.previousState}
2423
+ **New State:** ${result.newState}
2424
+
2425
+ ${result.previousState === 'Draft' ? '⚠️ Workflow was already in Draft state' : ''}`;
2426
+ return {
2427
+ content: [{
2428
+ type: "text",
2429
+ text: responseText
2430
+ }]
2431
+ };
2432
+ }
2433
+ catch (error) {
2434
+ console.error("Error deactivating workflow:", error);
2435
+ return {
2436
+ content: [{
2437
+ type: "text",
2438
+ text: `Failed to deactivate workflow: ${error.message}`
2439
+ }],
2440
+ isError: true
2441
+ };
2442
+ }
2443
+ });
2444
+ server.tool("activate-workflow", "Activate a workflow (set to Activated state). Use after modifying classic workflow definitions.", {
2445
+ workflowId: z.string().describe("GUID of the workflow to activate")
2446
+ }, async ({ workflowId }) => {
2447
+ try {
2448
+ const service = getPowerPlatformService();
2449
+ const result = await service.activateWorkflow(workflowId);
2450
+ const responseText = `✅ Workflow activated successfully
2451
+
2452
+ **Workflow:** ${result.workflowName}
2453
+ **Previous State:** ${result.previousState}
2454
+ **New State:** ${result.newState}
2455
+
2456
+ ${result.previousState === 'Activated' ? '⚠️ Workflow was already in Activated state' : ''}`;
2457
+ return {
2458
+ content: [{
2459
+ type: "text",
2460
+ text: responseText
2461
+ }]
2462
+ };
2463
+ }
2464
+ catch (error) {
2465
+ console.error("Error activating workflow:", error);
2466
+ return {
2467
+ content: [{
2468
+ type: "text",
2469
+ text: `Failed to activate workflow: ${error.message}`
2470
+ }],
2471
+ isError: true
2472
+ };
2473
+ }
2474
+ });
2475
+ server.tool("document-workflow-safe", "Safely document a workflow by automatically deactivating → documenting → reactivating. Atomic operation with rollback on failure. Recommended for classic workflows that require deactivation before modification.", {
2476
+ workflowId: z.string().describe("GUID of the workflow to document"),
2477
+ type: z.enum(['flow', 'workflow']).optional().describe("Type of automation (auto-detected if not provided)")
2478
+ }, async ({ workflowId, type }) => {
2479
+ try {
2480
+ const service = getPowerPlatformService();
2481
+ const result = await service.documentWorkflowSafe(workflowId, type);
2482
+ // Format the response
2483
+ const actionSummary = result.analysis.actionCount > 0
2484
+ ? `${result.analysis.actionCount} actions${result.analysis.actions.length > 0 ? ': ' + result.analysis.actions.slice(0, 5).join(', ') + (result.analysis.actionCount > 5 ? '...' : '') : ''}`
2485
+ : 'none';
2486
+ const stateWarning = result.stateManagement.finalState.includes('⚠️')
2487
+ ? `\n\n⚠️ **WARNING:** ${result.stateManagement.finalState}`
2488
+ : '';
2489
+ const responseText = `✅ Successfully documented workflow
2490
+
2491
+ **Workflow:** ${result.workflowName}
2492
+
2493
+ **Analysis:**
2494
+ - Tables Modified: ${result.analysis.tablesModified.join(', ') || 'none'}
2495
+ - Trigger: ${result.analysis.trigger}
2496
+ - Trigger Fields: ${result.analysis.triggerFields.join(', ') || 'none'}
2497
+ - Actions: ${actionSummary}
2498
+
2499
+ **Description Updated:** ${result.descriptionUpdated ? 'Yes' : 'No'}
2500
+
2501
+ **State Management:**
2502
+ - Initial State: ${result.stateManagement.initialState}
2503
+ - Was Deactivated: ${result.stateManagement.wasDeactivated ? 'Yes' : 'No'}
2504
+ - Was Reactivated: ${result.stateManagement.wasReactivated ? 'Yes' : 'No'}
2505
+ - Final State: ${result.stateManagement.finalState}${stateWarning}
2506
+
2507
+ **Previous Description:**
2508
+ ${result.previousDescription || '(empty)'}
2509
+
2510
+ **New Description:**
2511
+ ${result.newDescription}`;
2512
+ return {
2513
+ content: [{
2514
+ type: "text",
2515
+ text: responseText
2516
+ }]
2517
+ };
2518
+ }
2519
+ catch (error) {
2520
+ console.error("Error documenting workflow safely:", error);
2521
+ return {
2522
+ content: [{
2523
+ type: "text",
2524
+ text: `Failed to document workflow: ${error.message}`
2525
+ }],
2526
+ isError: true
2527
+ };
2528
+ }
2529
+ });
2530
+ server.tool("create-flow", "Create a new Power Automate flow from an existing template flow. Uses template-based creation by copying an existing flow's definition and modifying it.", {
2531
+ name: z.string().describe("Display name for the new flow"),
2532
+ templateFlowId: z.string().describe("GUID of the template flow to copy from"),
2533
+ description: z.string().optional().describe("Description for the new flow"),
2534
+ state: z.enum(['draft', 'activated']).optional().describe("Initial state (default: draft)"),
2535
+ connectionReferenceMappings: z.record(z.string()).optional().describe("Map of connection reference names to new connection IDs. Format: {'connectionRefName': 'newConnectionId'}")
2536
+ }, async ({ name, templateFlowId, description, state, connectionReferenceMappings }) => {
2537
+ try {
2538
+ const service = getPowerPlatformService();
2539
+ const result = await service.createFlow(name, templateFlowId, {
2540
+ description,
2541
+ state,
2542
+ connectionReferenceMappings
2543
+ });
2544
+ const responseText = `✅ Flow created successfully
2545
+
2546
+ **Flow ID:** ${result.flowId}
2547
+ **Flow Name:** ${result.flowName}
2548
+ **State:** ${result.state}
2549
+ **Connection References Updated:** ${result.connectionReferencesUpdated}
2550
+ ${result.warnings.length > 0 ? `\n⚠️ **Warnings:**\n${result.warnings.map((w) => `- ${w}`).join('\n')}` : ''}
2551
+
2552
+ ${result.state === 'draft' ? '💡 Use activate-flow to activate the flow when ready.' : ''}`;
2553
+ return {
2554
+ content: [{
2555
+ type: "text",
2556
+ text: responseText
2557
+ }]
2558
+ };
2559
+ }
2560
+ catch (error) {
2561
+ console.error("Error creating flow:", error);
2562
+ return {
2563
+ content: [{
2564
+ type: "text",
2565
+ text: `Failed to create flow: ${error.message}`
2566
+ }],
2567
+ isError: true
2568
+ };
2569
+ }
2570
+ });
2571
+ server.tool("delete-flow", "Delete a Power Automate flow. This operation is permanent and cannot be undone. Flow must be in Draft state before deletion.", {
2572
+ flowId: z.string().describe("GUID of the flow to delete"),
2573
+ confirm: z.boolean().describe("Confirmation flag - must be true to proceed with deletion (safety check)")
2574
+ }, async ({ flowId, confirm }) => {
2575
+ try {
2576
+ if (!confirm) {
2577
+ return {
2578
+ content: [{
2579
+ type: "text",
2580
+ text: "❌ Deletion cancelled: confirm parameter must be true to proceed"
2581
+ }],
2582
+ isError: true
2583
+ };
2584
+ }
2585
+ const service = getPowerPlatformService();
2586
+ const result = await service.deleteFlow(flowId);
2587
+ const responseText = `✅ Flow deleted successfully
2588
+
2589
+ **Flow ID:** ${result.flowId}
2590
+ **Flow Name:** ${result.flowName}
2591
+ **Previous State:** ${result.previousState}
2592
+
2593
+ ⚠️ This operation is permanent and cannot be undone.`;
2594
+ return {
2595
+ content: [{
2596
+ type: "text",
2597
+ text: responseText
2598
+ }]
2599
+ };
2600
+ }
2601
+ catch (error) {
2602
+ console.error("Error deleting flow:", error);
2603
+ return {
2604
+ content: [{
2605
+ type: "text",
2606
+ text: `Failed to delete flow: ${error.message}`
2607
+ }],
2608
+ isError: true
2609
+ };
2610
+ }
2611
+ });
2612
+ server.tool("clone-flow", "Clone an existing Power Automate flow with a new name. Creates an exact copy in Draft state with optional connection reference updates.", {
2613
+ sourceFlowId: z.string().describe("GUID of the flow to clone"),
2614
+ newName: z.string().describe("Display name for the cloned flow"),
2615
+ description: z.string().optional().describe("Description for the cloned flow (defaults to original description)"),
2616
+ updateConnectionReferences: z.boolean().optional().describe("If true, update connection references using mappings (default: false)"),
2617
+ connectionReferenceMappings: z.record(z.string()).optional().describe("Map of connection reference names to new connection IDs (only used if updateConnectionReferences=true)")
2618
+ }, async ({ sourceFlowId, newName, description, updateConnectionReferences, connectionReferenceMappings }) => {
2619
+ try {
2620
+ const service = getPowerPlatformService();
2621
+ const result = await service.cloneFlow(sourceFlowId, newName, {
2622
+ description,
2623
+ updateConnectionReferences,
2624
+ connectionReferenceMappings
2625
+ });
2626
+ const responseText = `✅ Flow cloned successfully
2627
+
2628
+ **Source Flow:** ${result.sourceFlowName} (${result.sourceFlowId})
2629
+ **New Flow ID:** ${result.newFlowId}
2630
+ **New Flow Name:** ${result.newFlowName}
2631
+ **State:** ${result.state}
2632
+ **Connection References Updated:** ${result.connectionReferencesUpdated}
2633
+
2634
+ 💡 Use activate-flow to activate the cloned flow when ready.`;
2635
+ return {
2636
+ content: [{
2637
+ type: "text",
2638
+ text: responseText
2639
+ }]
2640
+ };
2641
+ }
2642
+ catch (error) {
2643
+ console.error("Error cloning flow:", error);
2644
+ return {
2645
+ content: [{
2646
+ type: "text",
2647
+ text: `Failed to clone flow: ${error.message}`
2648
+ }],
2649
+ isError: true
2650
+ };
2651
+ }
2652
+ });
2653
+ server.tool("activate-flow", "Activate a Power Automate flow (set to Activated state). Flow must be valid and connections must be configured.", {
2654
+ flowId: z.string().describe("GUID of the flow to activate")
2655
+ }, async ({ flowId }) => {
2656
+ try {
2657
+ const service = getPowerPlatformService();
2658
+ const result = await service.activateFlow(flowId);
2659
+ const responseText = `✅ Flow activated successfully
2660
+
2661
+ **Flow:** ${result.workflowName}
2662
+ **Previous State:** ${result.previousState}
2663
+ **New State:** ${result.newState}
2664
+
2665
+ ${result.previousState === 'Activated' ? '⚠️ Flow was already in Activated state' : ''}`;
2666
+ return {
2667
+ content: [{
2668
+ type: "text",
2669
+ text: responseText
2670
+ }]
2671
+ };
2672
+ }
2673
+ catch (error) {
2674
+ console.error("Error activating flow:", error);
2675
+ return {
2676
+ content: [{
2677
+ type: "text",
2678
+ text: `Failed to activate flow: ${error.message}`
2679
+ }],
2680
+ isError: true
2681
+ };
2682
+ }
2683
+ });
2684
+ server.tool("deactivate-flow", "Deactivate a Power Automate flow (set to Draft state). Use before modifying flow definition or deleting.", {
2685
+ flowId: z.string().describe("GUID of the flow to deactivate")
2686
+ }, async ({ flowId }) => {
2687
+ try {
2688
+ const service = getPowerPlatformService();
2689
+ const result = await service.deactivateFlow(flowId);
2690
+ const responseText = `✅ Flow deactivated successfully
2691
+
2692
+ **Flow:** ${result.workflowName}
2693
+ **Previous State:** ${result.previousState}
2694
+ **New State:** ${result.newState}
2695
+
2696
+ ${result.previousState === 'Draft' ? '⚠️ Flow was already in Draft state' : ''}`;
2697
+ return {
2698
+ content: [{
2699
+ type: "text",
2700
+ text: responseText
2701
+ }]
2702
+ };
2703
+ }
2704
+ catch (error) {
2705
+ console.error("Error deactivating flow:", error);
2706
+ return {
2707
+ content: [{
2708
+ type: "text",
2709
+ text: `Failed to deactivate flow: ${error.message}`
2710
+ }],
2711
+ isError: true
2712
+ };
2713
+ }
2714
+ });
2715
+ console.error(`powerplatform-customization tools registered (${57} tools)`);
2457
2716
  }
2458
2717
  // CLI entry point (standalone execution)
2459
2718
  // Uses realpathSync to resolve symlinks created by npx