Installs and configures PAC CLI for scaffolding, building, and deploying PowerApps Component Framework (PCF) controls on macOS, Linux, Windows. Use for PCF project init, build, push.
npx claudepluginhub nickmeron/dataverse-mcp-serverThis skill uses the workspace's default tool permissions.
The user wants to work with PCF components using the Power Platform CLI (`pac`).
Creates React and Vite code apps for Power Apps. Scaffolds projects, checks prerequisites like Node.js and pac CLI, authenticates, builds, and deploys to Power Platform.
Creates, updates, and deploys Power Apps generative pages for model-driven apps using React 17, TypeScript, Fluent UI V9, and PAC CLI. Useful for building or updating pages in Power Apps.
Guides deployment of existing Power Pages code sites to environments using PAC CLI. Verifies tooling, authenticates, confirms targets, builds, and uploads.
Share bugs, ideas, or general feedback.
The user wants to work with PCF components using the Power Platform CLI (pac).
Argument provided: $ARGUMENTS
All pac commands (pac pcf init, pac pcf push, pac solution) work on macOS, Linux, and Windows. Do not tell the user otherwise.
Step 1 — Check if pac is already installed:
pac help
If this prints the command list, skip to Step 3.
Step 2 — Install pac (if not found):
Detect the OS and run the matching commands:
macOS / Linux:
# Requires .NET 9+
dotnet --version
# If dotnet is not installed: brew install dotnet
# PAC CLI 2.x has a broken NuGet package on macOS — use 1.52.1
dotnet tool install --global Microsoft.PowerApps.CLI.Tool --version 1.52.1
Windows:
dotnet tool install --global Microsoft.PowerApps.CLI.Tool
Or use the standalone MSI installer: https://aka.ms/PowerAppsCLI
Step 3 — Authenticate pac:
pac auth list
If no profiles exist, check whether the user already authenticated via the MCP authenticate tool. If so, reuse those credentials to create a pac profile automatically:
pac auth create \
--name MCP \
--url ACTIVE_ENVIRONMENT_URL \
--applicationId MCP_CLIENT_ID \
--clientSecret "MCP_CLIENT_SECRET" \
--tenant MCP_TENANT_ID
Replace the values with the credentials the user provided to the MCP authenticate tool. This avoids asking the user to authenticate twice.
If the user has NOT authenticated via MCP either, use the pac-auth skill.
mkdir MyControl && cd MyControl
pac pcf init --namespace Contoso --name MyControl --template field
--template field for field-level controls (bound to a single field)--template dataset for dataset controls (grids, galleries)--namespace should match the publisher prefix (e.g. Contoso, MyCompany)--framework react to use React framework (optional but recommended)With React:
pac pcf init --namespace Contoso --name MyControl --template field --framework react
npm install
MyControl/index.ts — Main control logic (init, updateView, destroy)ControlManifest.Input.xml — Declares properties, resources, feature usageMyControl/HelloWorld.tsx — React componentnpm run build
npm start watch
This opens a test harness at http://localhost:8181 with hot reload.
pac pcf push --publisher-prefix contoso
This creates a temporary solution and pushes to the connected environment. Quick for dev, not for production.
mkdir Solution && cd Solution
pac solution init --publisher-name Contoso --publisher-prefix contoso
pac solution add-reference --path ../MyControl
dotnet build
On Windows you can also use msbuild /t:build /restore instead of dotnet build.
cd /path/to/pcf-project
npm install
npm run build # one-time build
npm start watch # dev server with hot reload
Edit ControlManifest.Input.xml:
<property name="myNewProp" display-name-key="My New Property"
description-key="Description" of-type="SingleLine.Text"
usage="bound" required="true" />
Common of-type values:
SingleLine.Text, Multiple, WholeNumber, Decimal, CurrencyDateAndTime.DateOnly, DateAndTime.DateAndTimeTwoOptions (boolean), OptionSet, Lookup.SimpleFP (floating point)Then rebuild: npm run build
cd Solution
dotnet build --configuration Release
.zip file is in Solution/bin/Release/import_solution tool (base64 encode the zip first)<?xml version="1.0" encoding="utf-8" ?>
<manifest>
<control namespace="Contoso" constructor="MyControl" version="1.0.0"
display-name-key="MyControl" description-key="Description"
control-type="standard">
<!-- Bound property -->
<property name="value" display-name-key="Value"
of-type="SingleLine.Text" usage="bound" required="true" />
<!-- Input-only property -->
<property name="label" display-name-key="Label"
of-type="SingleLine.Text" usage="input" required="false"
default-value="Default Label" />
<!-- Dataset (for dataset template only) -->
<data-set name="dataSet" display-name-key="DataSet" />
<resources>
<code path="index.ts" order="1" />
<css path="css/MyControl.css" order="1" />
<resx path="strings/MyControl.1033.resx" version="1.0.0" />
</resources>
<!-- Feature usage declarations -->
<feature-usage>
<uses-feature name="Device.captureImage" required="true" />
<uses-feature name="Utility" required="true" />
<uses-feature name="WebAPI" required="true" />
</feature-usage>
</control>
</manifest>
// In updateView or init:
const result = await this._context.webAPI.retrieveMultipleRecords(
"account", "?$select=name&$top=10"
);
// index.ts
import * as React from "react";
import { createRoot, Root } from "react-dom/client";
import { MyComponent } from "./MyComponent";
export class MyControl implements ComponentFramework.StandardControl<IInputs, IOutputs> {
private _root: Root;
public init(context, notifyOutputChanged, state, container) {
this._root = createRoot(container);
}
public updateView(context) {
this._root.render(React.createElement(MyComponent, { value: context.parameters.value.raw }));
}
public destroy() { this._root.unmount(); }
}
--version 1.52.1.--version 1.52.1 instead.pac auth create or use the pac-auth skillnpm install firstpac auth listdotnet build instead (works on all platforms)