mirror of
https://github.com/github/awesome-copilot.git
synced 2026-04-11 02:35:55 +00:00
feat: add FlowStudio monitoring + governance skills, update debug + build + mcp (#1304)
- **New skill: flowstudio-power-automate-monitoring** — flow health, failure rates, maker inventory, Power Apps, environment/connection counts via FlowStudio MCP cached store tools. - **New skill: flowstudio-power-automate-governance** — 10 CoE-aligned governance workflows: compliance review, orphan detection, archive scoring, connector audit, notification management, classification/tagging, maker offboarding, security review, environment governance, governance dashboard. - **Updated flowstudio-power-automate-debug** — purely live API tools (no store dependencies), mandatory action output inspection step, resubmit clarified as working for ALL trigger types. - **Updated flowstudio-power-automate-build** — Step 1 uses list_live_flows (not list_store_flows) for the duplicate check, resubmit-first testing. - **Updated flowstudio-power-automate-mcp** — store tool catalog, response shapes verified against real API calls, set_store_flow_state shape fix. - Plugin version bumped to 2.0.0, all 5 skills listed in plugin.json. - Generated docs regenerated via npm start. All response shapes verified against real FlowStudio MCP API calls. All 10 governance workflows validated with real tenant data. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,11 +2,20 @@
|
||||
name: flowstudio-power-automate-build
|
||||
description: >-
|
||||
Build, scaffold, and deploy Power Automate cloud flows using the FlowStudio
|
||||
MCP server. Load this skill when asked to: create a flow, build a new flow,
|
||||
MCP server. Your agent constructs flow definitions, wires connections, deploys,
|
||||
and tests — all via MCP without opening the portal.
|
||||
Load this skill when asked to: create a flow, build a new flow,
|
||||
deploy a flow definition, scaffold a Power Automate workflow, construct a flow
|
||||
JSON, update an existing flow's actions, patch a flow definition, add actions
|
||||
to a flow, wire up connections, or generate a workflow definition from scratch.
|
||||
Requires a FlowStudio MCP subscription — see https://mcp.flowstudio.app
|
||||
metadata:
|
||||
openclaw:
|
||||
requires:
|
||||
env:
|
||||
- FLOWSTUDIO_MCP_TOKEN
|
||||
primaryEnv: FLOWSTUDIO_MCP_TOKEN
|
||||
homepage: https://mcp.flowstudio.app
|
||||
---
|
||||
|
||||
# Build & Deploy Power Automate Flows with FlowStudio MCP
|
||||
@@ -64,14 +73,15 @@ ENV = "<environment-id>" # e.g. Default-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
||||
Always look before you build to avoid duplicates:
|
||||
|
||||
```python
|
||||
results = mcp("list_store_flows",
|
||||
environmentName=ENV, searchTerm="My New Flow")
|
||||
results = mcp("list_live_flows", environmentName=ENV)
|
||||
|
||||
# list_store_flows returns a direct array (no wrapper object)
|
||||
if len(results) > 0:
|
||||
# list_live_flows returns { "flows": [...] }
|
||||
matches = [f for f in results["flows"]
|
||||
if "My New Flow".lower() in f["displayName"].lower()]
|
||||
|
||||
if len(matches) > 0:
|
||||
# Flow exists — modify rather than create
|
||||
# id format is "envId.flowId" — split to get the flow UUID
|
||||
FLOW_ID = results[0]["id"].split(".", 1)[1]
|
||||
FLOW_ID = matches[0]["id"] # plain UUID from list_live_flows
|
||||
print(f"Existing flow: {FLOW_ID}")
|
||||
defn = mcp("get_live_flow", environmentName=ENV, flowName=FLOW_ID)
|
||||
else:
|
||||
@@ -182,7 +192,7 @@ for connector in connectors_needed:
|
||||
> connection_references = ref_flow["properties"]["connectionReferences"]
|
||||
> ```
|
||||
|
||||
See the `power-automate-mcp` skill's **connection-references.md** reference
|
||||
See the `flowstudio-power-automate-mcp` skill's **connection-references.md** reference
|
||||
for the full connection reference structure.
|
||||
|
||||
---
|
||||
@@ -278,6 +288,8 @@ check = mcp("get_live_flow", environmentName=ENV, flowName=FLOW_ID)
|
||||
|
||||
# Confirm state
|
||||
print("State:", check["properties"]["state"]) # Should be "Started"
|
||||
# If state is "Stopped", use set_live_flow_state — NOT update_live_flow
|
||||
# mcp("set_live_flow_state", environmentName=ENV, flowName=FLOW_ID, state="Started")
|
||||
|
||||
# Confirm the action we added is there
|
||||
acts = check["properties"]["definition"]["actions"]
|
||||
@@ -294,38 +306,45 @@ print("Actions:", list(acts.keys()))
|
||||
> flow will do and wait for explicit approval before calling `trigger_live_flow`
|
||||
> or `resubmit_live_flow_run`.
|
||||
|
||||
### Updated flows (have prior runs)
|
||||
### Updated flows (have prior runs) — ANY trigger type
|
||||
|
||||
The fastest path — resubmit the most recent run:
|
||||
> **Use `resubmit_live_flow_run` first.** It works for EVERY trigger type —
|
||||
> Recurrence, SharePoint, connector webhooks, Button, and HTTP. It replays
|
||||
> the original trigger payload. Do NOT ask the user to manually trigger the
|
||||
> flow or wait for the next scheduled run.
|
||||
|
||||
```python
|
||||
runs = mcp("get_live_flow_runs", environmentName=ENV, flowName=FLOW_ID, top=1)
|
||||
if runs:
|
||||
# Works for Recurrence, SharePoint, connector triggers — not just HTTP
|
||||
result = mcp("resubmit_live_flow_run",
|
||||
environmentName=ENV, flowName=FLOW_ID, runName=runs[0]["name"])
|
||||
print(result)
|
||||
print(result) # {"resubmitted": true, "triggerName": "..."}
|
||||
```
|
||||
|
||||
### Flows already using an HTTP trigger
|
||||
### HTTP-triggered flows — custom test payload
|
||||
|
||||
Fire directly with a test payload:
|
||||
Only use `trigger_live_flow` when you need to send a **different** payload
|
||||
than the original run. For verifying a fix, `resubmit_live_flow_run` is
|
||||
better because it uses the exact data that caused the failure.
|
||||
|
||||
```python
|
||||
schema = mcp("get_live_flow_http_schema",
|
||||
environmentName=ENV, flowName=FLOW_ID)
|
||||
print("Expected body:", schema.get("triggerSchema"))
|
||||
print("Expected body:", schema.get("requestSchema"))
|
||||
|
||||
result = mcp("trigger_live_flow",
|
||||
environmentName=ENV, flowName=FLOW_ID,
|
||||
body={"name": "Test", "value": 1})
|
||||
print(f"Status: {result['status']}")
|
||||
print(f"Status: {result['responseStatus']}")
|
||||
```
|
||||
|
||||
### Brand-new non-HTTP flows (Recurrence, connector triggers, etc.)
|
||||
|
||||
A brand-new Recurrence or connector-triggered flow has no runs to resubmit
|
||||
and no HTTP endpoint to call. **Deploy with a temporary HTTP trigger first,
|
||||
test the actions, then swap to the production trigger.**
|
||||
A brand-new Recurrence or connector-triggered flow has **no prior runs** to
|
||||
resubmit and no HTTP endpoint to call. This is the ONLY scenario where you
|
||||
need the temporary HTTP trigger approach below. **Deploy with a temporary
|
||||
HTTP trigger first, test the actions, then swap to the production trigger.**
|
||||
|
||||
#### 7a — Save the real trigger, deploy with a temporary HTTP trigger
|
||||
|
||||
@@ -384,7 +403,7 @@ if run["status"] == "Failed":
|
||||
root = err["failedActions"][-1]
|
||||
print(f"Root cause: {root['actionName']} → {root.get('code')}")
|
||||
# Debug and fix the definition before proceeding
|
||||
# See power-automate-debug skill for full diagnosis workflow
|
||||
# See flowstudio-power-automate-debug skill for full diagnosis workflow
|
||||
```
|
||||
|
||||
#### 7c — Swap to the production trigger
|
||||
@@ -428,7 +447,7 @@ else:
|
||||
| `union(old_data, new_data)` | Old values override new (first-wins) | Use `union(new_data, old_data)` |
|
||||
| `split()` on potentially-null string | `InvalidTemplate` crash | Wrap with `coalesce(field, '')` |
|
||||
| Checking `result["error"]` exists | Always present; true error is `!= null` | Use `result.get("error") is not None` |
|
||||
| Flow deployed but state is "Stopped" | Flow won't run on schedule | Check connection auth; re-enable |
|
||||
| Flow deployed but state is "Stopped" | Flow won't run on schedule | Call `set_live_flow_state` with `state: "Started"` — do **not** use `update_live_flow` for state changes |
|
||||
| Teams "Chat with Flow bot" recipient as object | 400 `GraphUserDetailNotFound` | Use plain string with trailing semicolon (see below) |
|
||||
|
||||
### Teams `PostMessageToConversation` — Recipient Formats
|
||||
|
||||
Reference in New Issue
Block a user