Add local-power-automate-mcp skill (self-hosted, privacy-first Power Automate MCP) - #2340
Add local-power-automate-mcp skill (self-hosted, privacy-first Power Automate MCP)#2340prasadgd9022 wants to merge 5 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a self-hosted Power Automate MCP skill focused on local execution, Azure CLI authentication, and guarded Dataverse writes.
Changes:
- Documents MCP registration, authentication, tools, and safety patterns.
- Adds sovereign-cloud and oversized-response guidance.
- Publishes the skill in the generated catalog.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 10 comments.
| File | Description |
|---|---|
skills/local-power-automate-mcp/SKILL.md |
Defines the new skill and operational guidance. |
docs/README.skills.md |
Adds the skill to the generated index. |
…ooting, sovereign-cloud setup, dry-run/truncation warnings
|
Thanks for the detailed review — addressed in
|
|
@aaronpowell Please review the Pull request |
aaronpowell
left a comment
There was a problem hiding this comment.
PR's need to target the main branch
|
I'm not really sure I understand the value of this skill. It just seems like that it's acting as a skill that says you can use an MCP proxy in front of Power Automate or Flow Studio, but it doesn't actually provide an implementation of that, you still have to write an MCP server, so I'm not sure it really does anything. |
…write) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Thanks @aaronpowell — two things: 1. Base branch: the PR now targets 2. On value / "you still have to write an MCP server": you don't — there is a complete, ready-to-run open-source (MIT) reference server referenced throughout the skill: https://github.com/prasadgd9022/power-automate-mcp. You clone it and register the stdio launch command; the skill provides copy-paste registration for Copilot CLI, VS Code, and Claude, the This is deliberately the operational counterpart to the already-published
So the skill is a working, self-contained path (clone → register → run), not just "you can proxy Power Automate." I've pushed a commit adding an explicit "Nothing to build" callout up top so this is unmistakable to readers. Could you take another look? Happy to adjust framing if you'd still prefer it positioned differently. |
🔒 PR Risk Scan ResultsScanned 1 changed file(s).
✅ No matching risk patterns were detected in changed files.
|
🔍 Vally Lint Results✅ All checks passed
Summary
Full linter output |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
Suppressed comments (4)
skills/local-power-automate-mcp/SKILL.md:26
- The packages are listed but never installed, while the instructions say users can clone, register, and run the server. On a fresh machine the launch/probe commands will fail with missing-module errors; include the requirements installation step used by the referenced project.
> - Python packages: `mcp`, `azure-identity`, `requests`
skills/local-power-automate-mcp/SKILL.md:158
- This command only works if the user's current directory happens to be the cloned repository, but the setup never changes into that directory. Use the same absolute-path convention as the server launch command so connection verification works from anywhere.
python probe.py
skills/local-power-automate-mcp/SKILL.md:210
- The referenced implementation does not check for a
definitionkey: it computescontainsDefinitionwith a substring search overjson.dumps(parsed), which can also match a value containing that word. Describing this as a key-presence check can make agents over-trust the preview; document it as a textual heuristic.
> The dry-run for `update_flow_definition` only checks that the JSON *parses* and
> that a `definition` key is present. It does **not** validate that the
skills/local-power-automate-mcp/SKILL.md:261
- This row incorrectly combines GCC, GCC High, and DoD under the GCC API/audience. These clouds have separate Flow endpoints, so the documented values will send GCC High and DoD users to the wrong cloud and token acquisition/API calls will fail. Split the row by cloud using the Microsoft Power Platform endpoint mappings.
> | US Gov (GCC High / DoD) | `https://gov.api.flow.microsoft.us` | `https://service.flow.microsoft.us/.default` |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
Suppressed comments (7)
skills/local-power-automate-mcp/SKILL.md:25
- Mandatory: this clones and executes whatever is on a third-party repository's default branch under the user's Azure identity. A later upstream change or compromise would bypass this review and invalidate the documented privacy/write-safety guarantees. Pin the setup to an immutable, reviewed commit and update that pin deliberately.
> - The reference server (`server.py`) cloned locally —
> `git clone https://github.com/prasadgd9022/power-automate-mcp`
skills/local-power-automate-mcp/SKILL.md:3
- The privacy claim is too broad: the server returns tenant data to the configured MCP host, and cloud-backed hosts/models may process it outside the machine. Only the Power Platform API leg bypasses a third-party MCP vendor. Qualify this because users may select the skill specifically for data-residency requirements.
description: 'Foundation skill for driving Microsoft Power Automate from an AI agent through a self-hosted, privacy-first local MCP server that authenticates with the operator''s own Azure CLI (az login) identity — no third-party SaaS and no API keys, so tenant flow data is never routed through a hosted vendor (calls go straight to Microsoft over HTTPS). Covers stdio registration for GitHub Copilot CLI, VS Code, and Claude; the az login auth model, token scopes, and troubleshooting; the 11 read/write tools (Flow REST + Dataverse Web API); the confirm-guarded write-safety pattern; sovereign/government-cloud configuration; and oversized-response handling. Load this when the user needs Power Automate automation but cannot route tenant data through a hosted vendor. Reference implementation (MIT): https://github.com/prasadgd9022/power-automate-mcp'
skills/local-power-automate-mcp/SKILL.md:13
- This says tenant data never leaves the machine, but tool results are delivered to the MCP host and may be processed by its cloud model. State the narrower guarantee—that Power Platform API traffic bypasses a hosted MCP vendor—so regulated users can evaluate the host/model's separate data policy.
offerings. It connects an agent to a **local stdio MCP server** that talks
directly to Microsoft's own APIs using the operator's **existing Azure identity**,
so tenant flow data is **never routed through a third-party SaaS** — the only
network calls are HTTPS straight to Microsoft (`api.flow.microsoft.com` and your
environment's Dataverse). Internet access to those endpoints is still required.
skills/local-power-automate-mcp/SKILL.md:26
- The setup never installs these dependencies. On a clean machine, the subsequent server and probe commands fail with
ModuleNotFoundError; add the requirements installation command before registration.
> - Python packages: `mcp`, `azure-identity`, `requests`
skills/local-power-automate-mcp/SKILL.md:46
- This data-path row omits the MCP host/model leg. Flow and Dataverse API calls are direct, but their returned tenant data is still passed to the configured host and potentially its cloud model; the table should not imply end-to-end local processing.
| Data path | Tenant data traverses the vendor's cloud | **Direct** to `api.flow.microsoft.com` + Dataverse over HTTPS — no third-party SaaS in the path |
skills/local-power-automate-mcp/SKILL.md:158
- Registration does not place the user in the cloned repository, so this relative command fails unless their current directory happens to be its root. Use the absolute probe path, as the server registration examples do.
python probe.py
skills/local-power-automate-mcp/SKILL.md:220
- The referenced implementation does not check for a
definitionkey: it computescontainsDefinitionusing"definition" in json.dumps(parsed), so an unrelated string value can make the flag true. The current wording and edit loop present that flag as structural validation; document it as a substring hint and require independent structure validation before applying.
> The dry-run for `update_flow_definition` only checks that the JSON *parses* and
> that a `definition` key is present. It does **not** validate that the
> definition is complete, semantically correct, or safe to run — a valid-JSON but
> broken definition will still be accepted. Treat a passing dry-run as a syntax
> check, not a correctness guarantee.
|
So I understand that it's meant to be an alternative to using the paid service from Flow Studio, but how is it different to the Power Automate official plugin (which contains a MCP server) or Power Platform CLI MCP server? |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Suppressed comments (8)
skills/local-power-automate-mcp/SKILL.md:25
- This clone tracks mutable
main, then runs that code with access to the operator's Azure CLI identity and tenant data. Future or compromised upstream commits would therefore execute without being reviewed here. Pin an immutable commit/release (the upstream currently has no tags or releases) and document how maintainers update the pin.
> `git clone https://github.com/prasadgd9022/power-automate-mcp`
skills/local-power-automate-mcp/SKILL.md:283
- This second recovery instruction also omits the required process restart. The server captures
PA_MCP_MAX_RESPONSE_CHARSat startup, so changing the environment alone does not affect the running MCP server.
2. **Never feed a truncated `clientdata` into `update_flow_definition`.** A
`[truncated ...]` marker means the definition is incomplete; raise
`PA_MCP_MAX_RESPONSE_CHARS` and re-fetch the full row before any edit, or you
will overwrite the flow with a partial definition.
skills/local-power-automate-mcp/SKILL.md:261
- This row cannot cover both GCC High and DoD. Microsoft sources list different API hosts and audiences for each cloud; the shared
gov.api.flow.microsoft.us/service.flow.microsoft.uspair targets the wrong resources. Split the row into the cloud-specific values.
> | US Gov (GCC High / DoD) | `https://gov.api.flow.microsoft.us` | `https://service.flow.microsoft.us/.default` |
skills/local-power-automate-mcp/SKILL.md:13
- The “only network calls” claim omits authentication traffic. Both
AzureCliCredentialtoken refresh and the interactive fallback can contact Microsoft Entra ID/Azure CLI endpoints, so the privacy description should distinguish tenant flow-data routing from authentication traffic.
directly to Microsoft's own APIs using the operator's **existing Azure identity**,
so tenant flow data is **never routed through a third-party SaaS** — the only
network calls are HTTPS straight to Microsoft (`api.flow.microsoft.com` and your
environment's Dataverse). Internet access to those endpoints is still required.
skills/local-power-automate-mcp/SKILL.md:31
- The documented setup skips dependency installation, so a fresh clone fails at startup unless
mcp,azure-identity, andrequestshappen to be installed already. Add the upstreamrequirements.txtinstallation step before registration.
> the stdio launch command below, and go. This skill is the operational
skills/local-power-automate-mcp/SKILL.md:213
- This overstates the dry-run check. The referenced server computes
containsDefinitionwith"definition" in json.dumps(parsed), which is only a substring search and can be true when nodefinitionkey exists. Calling it a key-presence check gives unsafe confidence before a full overwrite.
> The dry-run for `update_flow_definition` only checks that the JSON *parses* and
> that a `definition` key is present. It does **not** validate that the
> definition is complete, semantically correct, or safe to run — a valid-JSON but
> broken definition will still be accepted. Treat a passing dry-run as a syntax
> check, not a correctness guarantee.
skills/local-power-automate-mcp/SKILL.md:225
PA_MCP_MAX_RESPONSE_CHARSis read only when the server process starts. Raising it without restarting the MCP subprocess leaves the old limit active, so this recovery sequence can keep returning the same truncated definition. Tell the user to set it for the subprocess and restart the host before re-fetching.
This issue also appears on line 280 of the same file.
> **Never build `update_flow_definition` from a truncated `get_flow_definition`
> response.** If `clientdata` came back truncated (see *Handling Oversized
> Responses*), re-fetch the full definition (raise `PA_MCP_MAX_RESPONSE_CHARS`)
> before editing — overwriting with a partial definition destroys the flow.
skills/local-power-automate-mcp/SKILL.md:158
probe.pyis referenced by a relative path, but the preceding clone/registration flow never changes into the cloned repository. Running this command from the user's current directory therefore fails with “can't open file.” Make the required working directory explicit.
python probe.py
|
Closing this. After comparing against the two Microsoft-official options @aaronpowell pointed out — the Power Automate / FlowAgent plugin (local stdio, Thanks for the review and the pointers, @aaronpowell — both are genuinely useful references. |
What
Adds a new Agent Skill:
local-power-automate-mcp— a foundation skill for driving Microsoft Power Automate from an AI agent through a self-hosted, privacy-first local MCP server that authenticates with the operator's own Azure CLI (az login) identity.Why it is not a duplicate
The repo already ships the
flowstudio-power-automate-*skill family, but those are built entirely around a hosted, paid MCP (remote HTTP endpoint,x-api-keyJWT, tenant data routed through the vendor cloud). This skill fills the gap they do not cover:az login(Azure CLI) identity auth instead of portal-issued API keys — no key to paste, RBAC-bounded by the signed-in userapi.flow.microsoft.com+ Dataverse)confirm=Truedry-run write-safety pattern for Dataverse writesPA_MCP_*env varsIt is open source (MIT) and not a paid service, so the paid-submission path does not apply.
Checklist
SKILL.mdwith frontmatter;namematches folder; single-quoteddescription(10–1024 chars)npm run skill:validate→local-power-automate-mcp is validnpm run build→ added todocs/README.skills.mdstagedbranchReference implementation (MIT): https://github.com/prasadgd9022/power-automate-mcp