@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/PowerPlatformService.d.ts +185 -680
- package/build/PowerPlatformService.d.ts.map +1 -1
- package/build/PowerPlatformService.js +451 -2843
- package/build/PowerPlatformService.js.map +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +328 -69
- package/build/index.js.map +1 -1
- package/package.json +3 -5
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 '
|
|
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,
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
1730
|
+
}, async ({ solutionUniqueName, componentId, componentType, addRequiredComponents }) => {
|
|
1777
1731
|
try {
|
|
1778
1732
|
const service = getPowerPlatformService();
|
|
1779
|
-
await service.addComponentToSolution(solutionUniqueName, componentId, componentType, addRequiredComponents ?? true
|
|
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,
|
|
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: ${
|
|
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
|
-
|
|
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
|