[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6MJVAA46Z2WFS6NENJSHWFH":3,"skill-same:01M6MJVAA46Z2WFS6NENJSHWFH":104},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":26,"publishedAt":49,"linkOnly":50,"markdownContent":51,"markdownBody":52,"frontMatter":53,"refName":54,"commitSha":55,"skillDirectory":56,"forksCount":57,"repositoryHtmlUrl":58,"repositoryHomepageUrl":59,"ownerHtmlUrl":60,"ownerBlogUrl":61,"ownerDescription":62,"updatedAt":63,"install":64,"resources":77},"01M6MJVAA46Z2WFS6NENJSHWFH","power-automate-build",null,"Build, scaffold, and deploy Power Automate cloud flows using the FlowStudio 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:\u002F\u002Fmcp.flowstudio.app","hashgraph-online\u002Fawesome-codex-plugins","hashgraph-online","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F160371962?v=4","01M6CNB6NRJVNNGN14TR01Q6D3","HOL (Hashgraph Online)","01M6JT1HSKKG9V68KQAQGBA7XP",1571,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fninihen1\u002Fpower-automate-mcp-skills\u002Fskills\u002Fpower-automate-build\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000011","运维与部署","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48],"power automate build","build","automate","power","up","new","when","definition","flows","add","app","constructs","patch","MCP","flow","actions","server","update","generate","create","workflow","mcp server","2026-11-10 10:12:30",false,"---\nname: power-automate-build\ndescription: >-\n  Build, scaffold, and deploy Power Automate cloud flows using the FlowStudio\n  MCP server. Your agent constructs flow definitions, wires connections, deploys,\n  and tests — all via MCP without opening the portal.\n  Load this skill when asked to: create a flow, build a new flow,\n  deploy a flow definition, scaffold a Power Automate workflow, construct a flow\n  JSON, update an existing flow's actions, patch a flow definition, add actions\n  to a flow, wire up connections, or generate a workflow definition from scratch.\n  Requires a FlowStudio MCP subscription — see https:\u002F\u002Fmcp.flowstudio.app\n---\n\n# Build & Deploy Power Automate Flows with FlowStudio MCP\n\nStep-by-step guide for constructing and deploying Power Automate cloud flows\nprogrammatically through the FlowStudio MCP server.\n\n**Prerequisite**: A FlowStudio MCP server must be reachable with a valid JWT.\nSee the `power-automate-mcp` skill for connection setup.\nSubscribe at https:\u002F\u002Fmcp.flowstudio.app\n\nWorkflow:\n1. Load current build tools.\n2. Check for an existing flow.\n3. Resolve connection references.\n4. Build the definition.\n5. Deploy.\n6. Verify.\n7. Test.\n\n---\n\n## Source of Truth\n\n> **Always call `list_skills` \u002F `tool_search` first** to confirm available tool\n> names and parameter schemas. Tool names and parameters may change between\n> server versions.\n> This skill covers response shapes, behavioral notes, and build patterns —\n> things tool schemas cannot tell you. If this document disagrees with\n> `tool_search` or a real API response, the API wins.\n\n---\n\n## Python Helper\n\n```python\nimport json, urllib.request\n\nMCP_URL   = \"https:\u002F\u002Fmcp.flowstudio.app\u002Fmcp\"\nMCP_TOKEN = \"\u003CYOUR_JWT_TOKEN>\"\n\ndef mcp(tool, **kwargs):\n    payload = json.dumps({\"jsonrpc\": \"2.0\", \"id\": 1, \"method\": \"tools\u002Fcall\",\n                          \"params\": {\"name\": tool, \"arguments\": kwargs}}).encode()\n    req = urllib.request.Request(MCP_URL, data=payload,\n        headers={\"x-api-key\": MCP_TOKEN, \"Content-Type\": \"application\u002Fjson\",\n                 \"User-Agent\": \"FlowStudio-MCP\u002F1.0\"})\n    try:\n        resp = urllib.request.urlopen(req, timeout=120)\n    except urllib.error.HTTPError as e:\n        body = e.read().decode(\"utf-8\", errors=\"replace\")\n        raise RuntimeError(f\"MCP HTTP {e.code}: {body[:200]}\") from e\n    raw = json.loads(resp.read())\n    if \"error\" in raw:\n        raise RuntimeError(f\"MCP error: {json.dumps(raw['error'])}\")\n    return json.loads(raw[\"result\"][\"content\"][0][\"text\"])\n\nENV = \"\u003Cenvironment-id>\"  # e.g. Default-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n```\n\n---\n\n## 0. Load the Current Build Tools\n\nFor a brand-new flow, load the server's `create-flow` bundle. For editing an\nexisting flow, load `build-flow`. This keeps the agent aligned with the MCP\nserver's current schema before constructing JSON.\n\n```python\nschemas = mcp(\"tool_search\", query=\"skill:create-flow\")\n# Includes list_live_environments, list_live_connections,\n# describe_live_connector, get_live_dynamic_options, update_live_flow.\n```\n\nIf you need a tool outside the bundle, load it explicitly:\n\n```python\nmcp(\"tool_search\", query=\"select:get_live_dynamic_properties\")\n```\n\n---\n\n## 1. Safety Check: Does the Flow Already Exist?\n\nAlways look before you build to avoid duplicates:\n\n```python\nresults = mcp(\"list_live_flows\",\n    environmentName=ENV,\n    mode=\"owner\",\n    search=\"My New Flow\",\n    top=20)\n\n# list_live_flows returns { \"flows\": [...], \"mode\": \"...\", ... }\nmatches = [f for f in results[\"flows\"]\n           if \"My New Flow\".lower() in f[\"displayName\"].lower()]\n\nif len(matches) > 0:\n    # Flow exists — modify rather than create\n    FLOW_ID = matches[0][\"id\"]   # plain UUID from list_live_flows\n    print(f\"Existing flow: {FLOW_ID}\")\n    defn = mcp(\"get_live_flow\", environmentName=ENV, flowName=FLOW_ID)\nelse:\n    print(\"Flow not found — building from scratch\")\n    FLOW_ID = None\n```\n\nFor very large environments, `list_live_flows` may return a continuation URL.\nPass it back as `continuationUrl` with the same `mode` to retrieve the next\nbatch. Use `mode=\"admin\"` only when the user needs all environment flows and\nthe MCP identity has admin rights.\n\n---\n\n## 2. Obtain Connection References\n\nEvery connector action needs a `connectionName` that points to a key in the\nflow's `connectionReferences` map. That key links to an authenticated connection\nin the environment.\n\n> **MANDATORY**: You MUST call `list_live_connections` first — do NOT ask the\n> user for connection names or GUIDs. The API returns the exact values you need.\n> Only prompt the user if the API confirms that required connections are missing.\n\n### 2a — Find active connections\n\n```python\nconns = mcp(\"list_live_connections\", environmentName=ENV)\nactive = [c for c in conns[\"connections\"]\n          if c[\"statuses\"][0][\"status\"] == \"Connected\"]\nconn_map = {c[\"connectorName\"]: c[\"id\"] for c in active}\n```\n\nFor a known connector, pass `search` to reduce output and get paste-ready\n`connectionReferenceTemplate` and `hostTemplate` values:\n\n```python\nsp_conns = mcp(\"list_live_connections\",\n    environmentName=ENV,\n    search=\"shared_sharepointonline\")\n```\n\n### 2b — Determine which connectors the flow needs\n\nCommon connector API names: SharePoint `shared_sharepointonline`, Outlook\n`shared_office365`, Teams `shared_teams`, Approvals `shared_approvals`,\nOneDrive `shared_onedriveforbusiness`, Excel `shared_excelonlinebusiness`,\nDataverse `shared_commondataserviceforapps`, Forms `shared_microsoftforms`.\n\nFlows that need no connectors, such as Recurrence + Compose + HTTP only, can\nomit `connectionReferences`.\n\n### 2c — If connections are missing, guide the user\n\n```python\nconnectors_needed = [\"shared_sharepointonline\", \"shared_office365\"]  # adjust per flow\nmissing = [c for c in connectors_needed if c not in conn_map]\nif missing:\n    # STOP: connections require browser OAuth consent.\n    # Ask the user to create the missing connector connections in the\n    # selected environment, then re-run list_live_connections.\n    raise Exception(f\"Missing active connections: {missing}\")\n```\n\n### 2d — Build the connectionReferences block\n\n```python\nconnection_references = {}\nhost_templates = {}\nfor connector in connectors_needed:\n    c = next(c for c in active if c[\"connectorName\"] == connector)\n    connection_references[connector] = c.get(\"connectionReferenceTemplate\") or {\n        \"connectionName\": c[\"id\"],   # the connection id from list_live_connections\n        \"source\": \"Invoker\",\n        \"id\": f\"\u002Fproviders\u002FMicrosoft.PowerApps\u002Fapis\u002F{connector}\"\n    }\n    host_templates[connector] = c.get(\"hostTemplate\") or {\n        \"connectionName\": connector\n    }\n```\n\nIn Step 3 action JSON, `inputs.host.connectionName` must be the map key such as\n`shared_teams`, not the GUID. The GUID belongs only inside the\n`connectionReferences[connector].connectionName` value. If an existing flow uses\nthe same connectors, you may also copy its `properties.connectionReferences`\nfrom `get_live_flow`.\n\n---\n\n## 3. Build the Flow Definition\n\nConstruct the definition object. See [flow-schema.md](references\u002Fflow-schema.md)\nfor the full schema and these action pattern references for copy-paste templates:\n- [action-patterns-core.md](references\u002Faction-patterns-core.md) — Variables, control flow, expressions\n- [action-patterns-data.md](references\u002Faction-patterns-data.md) — Array transforms, HTTP, parsing\n- [action-patterns-connectors.md](references\u002Faction-patterns-connectors.md) — SharePoint, Outlook, Teams, Approvals\n\n```python\ndefinition = {\n    \"$schema\": \"https:\u002F\u002Fschema.management.azure.com\u002Fproviders\u002FMicrosoft.Logic\u002Fschemas\u002F2016-06-01\u002Fworkflowdefinition.json#\",\n    \"contentVersion\": \"1.0.0.0\",\n    \"triggers\": { ... },   # see trigger-types.md \u002F build-patterns.md\n    \"actions\": { ... }     # see ACTION-PATTERNS-*.md \u002F build-patterns.md\n}\n```\n\n> See [build-patterns.md](references\u002Fbuild-patterns.md) for complete, ready-to-use\n> flow definitions covering Recurrence+SharePoint+Teams, HTTP triggers, and more.\n\n### Discover connector operations before guessing JSON\n\nFor connector-backed triggers\u002Factions, prefer the live connector describer over\nhand-written shapes. It can return authored hints, canonical examples, variant\nkeys, inputs\u002Foutputs, and dynamic metadata pointers.\n\n```python\n# Search across connectors when you know the user's intent but not the API.\nmatches = mcp(\"describe_live_connector\",\n    environmentName=ENV,\n    search=\"send email\",\n    top=5)\n\n# Describe a specific operation before copying an exampleDefinition.\nop = mcp(\"describe_live_connector\",\n    environmentName=ENV,\n    connectorName=\"shared_office365\",\n    operationId=\"SendEmailV2\")\nprint(op.get(\"hint\"))\n```\n\nWhen an operation has multiple authored variants, request the variant the flow\nneeds:\n\n```python\nteams_chat = mcp(\"describe_live_connector\",\n    environmentName=ENV,\n    connectorName=\"shared_teams\",\n    operationId=\"PostMessageToConversation\",\n    variant=\"flowbot_chat\")\n```\n\nWhen the operation description says a parameter has dynamic options or dynamic\nproperties, call the indicated next tool:\n\n```python\nsp_op = mcp(\"describe_live_connector\",\n    environmentName=ENV,\n    connectorName=\"shared_sharepointonline\",\n    operationId=\"GetItems\")\n\nsites = mcp(\"get_live_dynamic_options\",\n    environmentName=ENV,\n    connectorName=\"shared_sharepointonline\",\n    connectionName=conn_map[\"shared_sharepointonline\"],\n    operationId=\"GetItems\",\n    parameterName=\"dataset\",\n    dynamicMetadata=sp_op[\"dynamicParameters\"][\"dataset\"])\n\nfields = mcp(\"get_live_dynamic_properties\",\n    environmentName=ENV,\n    connectorName=\"shared_sharepointonline\",\n    connectionName=conn_map[\"shared_sharepointonline\"],\n    operationId=\"GetItems\",\n    parameterName=\"item\",\n    parameters={\"dataset\": \"\u003Csite-url>\", \"table\": \"\u003Clist-id>\"},\n    dynamicMetadata=sp_op[\"dynamicProperties\"][\"item\"])\n```\n\nUse dynamic options for dropdown IDs such as SharePoint sites\u002Flists and Teams\nteams\u002Fchannels. Use dynamic properties for schema\u002Ffield shapes such as\nSharePoint list item columns.\n\n---\n\n## 4. Deploy (Create or Update)\n\n`update_live_flow` handles both creation and updates in a single tool.\n\n### Create a new flow (no existing flow)\n\nOmit `flowName` — the server generates a new GUID and creates via PUT:\n\n```python\ndefinition[\"description\"] = \"Weekly SharePoint → Teams notification flow, built by agent\"\n\nresult = mcp(\"update_live_flow\",\n    environmentName=ENV,\n    # flowName omitted → creates a new flow\n    definition=definition,\n    connectionReferences=connection_references,\n    displayName=\"Overdue Invoice Notifications\"\n)\n\nif result.get(\"error\") is not None:\n    print(\"Create failed:\", result[\"error\"])\nelse:\n    # Capture the new flow ID for subsequent steps\n    FLOW_ID = result[\"created\"]\n    print(f\"✅ Flow created: {FLOW_ID}\")\n```\n\n### Update an existing flow\n\nProvide `flowName` to PATCH:\n\n```python\ndefinition[\"description\"] = (\n    \"Updated by agent on \" + __import__('datetime').datetime.utcnow().isoformat()\n)\n\nresult = mcp(\"update_live_flow\",\n    environmentName=ENV,\n    flowName=FLOW_ID,\n    definition=definition,\n    connectionReferences=connection_references,\n    displayName=\"My Updated Flow\"\n)\n\nif result.get(\"error\") is not None:\n    print(\"Update failed:\", result[\"error\"])\nelse:\n    print(\"Update succeeded:\", result)\n```\n\n> ⚠️ `update_live_flow` always returns an `error` key.\n> `null` (Python `None`) means success — do not treat the presence of the key as failure.\n>\n> ⚠️ Flow description lives at `definition[\"description\"]`. The current server\n> appends `#flowstudio-mcp` for usage tracking. Do not pass a top-level\n> `description` argument unless `tool_search` shows one in the active schema.\n\n### Common deployment errors\n\n| Error message (contains) | Cause | Fix |\n|---|---|---|\n| `missing from connectionReferences` | An action's `host.connectionName` references a key that doesn't exist in the `connectionReferences` map | Ensure `host.connectionName` uses the **key** from `connectionReferences` (e.g. `shared_teams`), not the raw GUID |\n| `ConnectionAuthorizationFailed` \u002F 403 | The connection GUID belongs to another user or is not authorized | Re-run Step 2a and use a connection owned by the current `x-api-key` user |\n| `InvalidTemplate` \u002F `InvalidDefinition` | Syntax error in the definition JSON | Check `runAfter` chains, expression syntax, and action type spelling |\n| `ConnectionNotConfigured` | A connector action exists but the connection GUID is invalid or expired | Re-check `list_live_connections` for a fresh GUID |\n\n---\n\n## 5. Verify the Deployment\n\n```python\ncheck = mcp(\"get_live_flow\", environmentName=ENV, flowName=FLOW_ID)\n\n# Confirm state\nprint(\"State:\", check[\"properties\"][\"state\"])  # Should be \"Started\"\n# If state is \"Stopped\", use set_live_flow_state — NOT update_live_flow\n# mcp(\"set_live_flow_state\", environmentName=ENV, flowName=FLOW_ID, state=\"Started\")\n\n# Confirm the action we added is there\nacts = check[\"properties\"][\"definition\"][\"actions\"]\nprint(\"Actions:\", list(acts.keys()))\n```\n\n---\n\n## 6. Test the Flow\n\n> **MANDATORY**: Before triggering any test run, **ask the user for confirmation**.\n> Running a flow has real side effects — it may send emails, post Teams messages,\n> write to SharePoint, start approvals, or call external APIs. Explain what the\n> flow will do and wait for explicit approval before calling `trigger_live_flow`\n> or `resubmit_live_flow_run`.\n\n### Updated flows (have prior runs) — ANY trigger type\n\n> **Use `resubmit_live_flow_run` first.** It works for EVERY trigger type —\n> Recurrence, SharePoint, connector webhooks, Button, and HTTP. It replays\n> the original trigger payload. Do NOT ask the user to manually trigger the\n> flow or wait for the next scheduled run.\n\n```python\nruns = mcp(\"get_live_flow_runs\", environmentName=ENV, flowName=FLOW_ID, top=1)\nif runs:\n    # Works for Recurrence, SharePoint, connector triggers — not just HTTP\n    result = mcp(\"resubmit_live_flow_run\",\n        environmentName=ENV, flowName=FLOW_ID, runName=runs[0][\"name\"])\n    print(result)   # {\"resubmitted\": true, \"triggerName\": \"...\"}\n```\n\n### HTTP, Button, and PowerApps flows — custom test payload\n\nOnly use `trigger_live_flow` when you need to send a **different** payload\nthan the original run. For verifying a fix, `resubmit_live_flow_run` is\nbetter because it uses the exact data that caused the failure.\n\n```python\ndefn = mcp(\"get_live_flow\", environmentName=ENV, flowName=FLOW_ID)\ntriggers = defn[\"properties\"][\"definition\"][\"triggers\"]\nmanual = next(iter(triggers.values()))\nprint(\"Expected body:\", manual.get(\"inputs\", {}).get(\"schema\"))\n\nresult = mcp(\"trigger_live_flow\",\n    environmentName=ENV, flowName=FLOW_ID,\n    body={\"name\": \"Test\", \"value\": 1})\nprint(f\"Status: {result['responseStatus']}, via: {result['invocation']}\")\nprint(result.get(\"warning\"))   # set when a required input was missing: the run still ran, with null\n```\n\n### Brand-new non-HTTP flows\n\nA brand-new **Recurrence** flow needs no workaround: deploy it, then run it\nimmediately with `trigger_live_flow` and no `body` — same as the portal's\n\"Run flow\" button. A body is refused; scheduled triggers take no inputs.\n\nA brand-new **connector-triggered** flow (SharePoint, webhooks) has no prior\nruns and cannot fire without a real source event. Deploy with a temporary\nHTTP trigger, test the actions, then swap to the production trigger:\n\n```python\nproduction_trigger = definition[\"triggers\"]\ndefinition[\"triggers\"] = {\n    \"manual\": {\"type\": \"Request\", \"kind\": \"Http\", \"inputs\": {\"schema\": {}}}\n}\nresult = mcp(\"update_live_flow\", environmentName=ENV,\n    flowName=FLOW_ID,       # omit if creating new\n    definition=definition, connectionReferences=connection_references,\n    displayName=\"Overdue Invoice Notifications\")\nFLOW_ID = FLOW_ID or result[\"flowName\"]\n\nmcp(\"trigger_live_flow\", environmentName=ENV, flowName=FLOW_ID,\n    body={\"sample\": \"payload\"})\nruns = mcp(\"get_live_flow_runs\", environmentName=ENV, flowName=FLOW_ID, top=1)\nif runs[0][\"status\"] == \"Failed\":\n    err = mcp(\"get_live_flow_run_error\",\n        environmentName=ENV, flowName=FLOW_ID, runName=runs[0][\"name\"])\n    raise Exception(err[\"failedActions\"][-1])\n\ndefinition[\"triggers\"] = production_trigger\nmcp(\"update_live_flow\", environmentName=ENV, flowName=FLOW_ID,\n    definition=definition, connectionReferences=connection_references)\n```\n\nThe trigger is only the entry point; testing through HTTP still exercises the\nsame actions. If actions use `triggerBody()` or `triggerOutputs()`, pass a\nrepresentative `body` shaped like the production trigger payload.\n\n---\n\n## Gotchas\n\n| Mistake | Consequence | Prevention |\n|---|---|---|\n| Missing `connectionReferences` in deploy | 400 \"Supply connectionReferences\" | Always call `list_live_connections` first |\n| `\"operationOptions\"` missing on Foreach | Parallel execution, race conditions on writes | Always add `\"Sequential\"` |\n| `union(old_data, new_data)` | Old values override new (first-wins) | Use `union(new_data, old_data)` |\n| `split()` on potentially-null string | `InvalidTemplate` crash | Wrap with `coalesce(field, '')` |\n| Checking `result[\"error\"]` exists | Always present; true error is `!= null` | Use `result.get(\"error\") is not None` |\n| 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 |\n| Teams \"Chat with Flow bot\" recipient as object | 400 `GraphUserDetailNotFound` | Use plain string with trailing semicolon (see below) |\n| Copilot\u002FSkills flow not in a solution | Copilot Studio may not discover it as an agent tool | After deploy, call `add_live_flow_to_solution` with the target `solutionId` |\n| Button\u002FSkills trigger used for MCP testing | Runs even when a required input is missing (null) | Pass inputs in `trigger_live_flow` `body`; on `warning`, cancel and retry with the full body |\n| Connector action missing `metadata.operationMetadataId` | Designer\u002Frun-only UI can behave inconsistently | Preserve existing IDs; add stable GUIDs for new connector actions |\n| Placeholder Excel `scriptId` | Dynamic validation fails at save time | Resolve the real Office Script ID before deploying |\n| SharePoint `PatchItem` omits required fields | Save can fail even if the field is not changing | Echo unchanged required fields such as `item\u002FTitle` |\n| Copilot Studio connector calls a draft agent | Connector invocation can fail or hit stale behavior | Publish the agent before testing\u002Fresubmitting the flow |\n\n### Teams `PostMessageToConversation` — Recipient Formats\n\nThe `body\u002Frecipient` parameter format depends on the `location` value:\n\n| Location | `body\u002Frecipient` format | Example |\n|---|---|---|\n| **Chat with Flow bot** | Plain email string with **trailing semicolon** | `\"user@contoso.com;\"` |\n| **Channel** | Object with `groupId` and `channelId` | `{\"groupId\": \"...\", \"channelId\": \"...\"}` |\n\n> **Common mistake**: passing `{\"to\": \"user@contoso.com\"}` for \"Chat with Flow bot\"\n> returns a 400 `GraphUserDetailNotFound` error. The API expects a plain string.\n\n---\n\n## Reference Files\n\n- [flow-schema.md](references\u002Fflow-schema.md) — Full flow definition JSON schema\n- [trigger-types.md](references\u002Ftrigger-types.md) — Trigger type templates\n- [action-patterns-core.md](references\u002Faction-patterns-core.md) — Variables, control flow, expressions\n- [action-patterns-data.md](references\u002Faction-patterns-data.md) — Array transforms, HTTP, parsing\n- [action-patterns-connectors.md](references\u002Faction-patterns-connectors.md) — SharePoint, Outlook, Teams, Approvals\n- [build-patterns.md](references\u002Fbuild-patterns.md) — Complete flow definition templates (Recurrence+SP+Teams, HTTP trigger)\n\n## Related Skills\n\n- `power-automate-mcp` — Core connection setup and tool reference\n- `power-automate-debug` — Debug failing flows after deployment\n","# Build & Deploy Power Automate Flows with FlowStudio MCP\n\nStep-by-step guide for constructing and deploying Power Automate cloud flows\nprogrammatically through the FlowStudio MCP server.\n\n**Prerequisite**: A FlowStudio MCP server must be reachable with a valid JWT.\nSee the `power-automate-mcp` skill for connection setup.\nSubscribe at https:\u002F\u002Fmcp.flowstudio.app\n\nWorkflow:\n1. Load current build tools.\n2. Check for an existing flow.\n3. Resolve connection references.\n4. Build the definition.\n5. Deploy.\n6. Verify.\n7. Test.\n\n---\n\n## Source of Truth\n\n> **Always call `list_skills` \u002F `tool_search` first** to confirm available tool\n> names and parameter schemas. Tool names and parameters may change between\n> server versions.\n> This skill covers response shapes, behavioral notes, and build patterns —\n> things tool schemas cannot tell you. If this document disagrees with\n> `tool_search` or a real API response, the API wins.\n\n---\n\n## Python Helper\n\n```python\nimport json, urllib.request\n\nMCP_URL   = \"https:\u002F\u002Fmcp.flowstudio.app\u002Fmcp\"\nMCP_TOKEN = \"\u003CYOUR_JWT_TOKEN>\"\n\ndef mcp(tool, **kwargs):\n    payload = json.dumps({\"jsonrpc\": \"2.0\", \"id\": 1, \"method\": \"tools\u002Fcall\",\n                          \"params\": {\"name\": tool, \"arguments\": kwargs}}).encode()\n    req = urllib.request.Request(MCP_URL, data=payload,\n        headers={\"x-api-key\": MCP_TOKEN, \"Content-Type\": \"application\u002Fjson\",\n                 \"User-Agent\": \"FlowStudio-MCP\u002F1.0\"})\n    try:\n        resp = urllib.request.urlopen(req, timeout=120)\n    except urllib.error.HTTPError as e:\n        body = e.read().decode(\"utf-8\", errors=\"replace\")\n        raise RuntimeError(f\"MCP HTTP {e.code}: {body[:200]}\") from e\n    raw = json.loads(resp.read())\n    if \"error\" in raw:\n        raise RuntimeError(f\"MCP error: {json.dumps(raw['error'])}\")\n    return json.loads(raw[\"result\"][\"content\"][0][\"text\"])\n\nENV = \"\u003Cenvironment-id>\"  # e.g. Default-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx\n```\n\n---\n\n## 0. Load the Current Build Tools\n\nFor a brand-new flow, load the server's `create-flow` bundle. For editing an\nexisting flow, load `build-flow`. This keeps the agent aligned with the MCP\nserver's current schema before constructing JSON.\n\n```python\nschemas = mcp(\"tool_search\", query=\"skill:create-flow\")\n# Includes list_live_environments, list_live_connections,\n# describe_live_connector, get_live_dynamic_options, update_live_flow.\n```\n\nIf you need a tool outside the bundle, load it explicitly:\n\n```python\nmcp(\"tool_search\", query=\"select:get_live_dynamic_properties\")\n```\n\n---\n\n## 1. Safety Check: Does the Flow Already Exist?\n\nAlways look before you build to avoid duplicates:\n\n```python\nresults = mcp(\"list_live_flows\",\n    environmentName=ENV,\n    mode=\"owner\",\n    search=\"My New Flow\",\n    top=20)\n\n# list_live_flows returns { \"flows\": [...], \"mode\": \"...\", ... }\nmatches = [f for f in results[\"flows\"]\n           if \"My New Flow\".lower() in f[\"displayName\"].lower()]\n\nif len(matches) > 0:\n    # Flow exists — modify rather than create\n    FLOW_ID = matches[0][\"id\"]   # plain UUID from list_live_flows\n    print(f\"Existing flow: {FLOW_ID}\")\n    defn = mcp(\"get_live_flow\", environmentName=ENV, flowName=FLOW_ID)\nelse:\n    print(\"Flow not found — building from scratch\")\n    FLOW_ID = None\n```\n\nFor very large environments, `list_live_flows` may return a continuation URL.\nPass it back as `continuationUrl` with the same `mode` to retrieve the next\nbatch. Use `mode=\"admin\"` only when the user needs all environment flows and\nthe MCP identity has admin rights.\n\n---\n\n## 2. Obtain Connection References\n\nEvery connector action needs a `connectionName` that points to a key in the\nflow's `connectionReferences` map. That key links to an authenticated connection\nin the environment.\n\n> **MANDATORY**: You MUST call `list_live_connections` first — do NOT ask the\n> user for connection names or GUIDs. The API returns the exact values you need.\n> Only prompt the user if the API confirms that required connections are missing.\n\n### 2a — Find active connections\n\n```python\nconns = mcp(\"list_live_connections\", environmentName=ENV)\nactive = [c for c in conns[\"connections\"]\n          if c[\"statuses\"][0][\"status\"] == \"Connected\"]\nconn_map = {c[\"connectorName\"]: c[\"id\"] for c in active}\n```\n\nFor a known connector, pass `search` to reduce output and get paste-ready\n`connectionReferenceTemplate` and `hostTemplate` values:\n\n```python\nsp_conns = mcp(\"list_live_connections\",\n    environmentName=ENV,\n    search=\"shared_sharepointonline\")\n```\n\n### 2b — Determine which connectors the flow needs\n\nCommon connector API names: SharePoint `shared_sharepointonline`, Outlook\n`shared_office365`, Teams `shared_teams`, Approvals `shared_approvals`,\nOneDrive `shared_onedriveforbusiness`, Excel `shared_excelonlinebusiness`,\nDataverse `shared_commondataserviceforapps`, Forms `shared_microsoftforms`.\n\nFlows that need no connectors, such as Recurrence + Compose + HTTP only, can\nomit `connectionReferences`.\n\n### 2c — If connections are missing, guide the user\n\n```python\nconnectors_needed = [\"shared_sharepointonline\", \"shared_office365\"]  # adjust per flow\nmissing = [c for c in connectors_needed if c not in conn_map]\nif missing:\n    # STOP: connections require browser OAuth consent.\n    # Ask the user to create the missing connector connections in the\n    # selected environment, then re-run list_live_connections.\n    raise Exception(f\"Missing active connections: {missing}\")\n```\n\n### 2d — Build the connectionReferences block\n\n```python\nconnection_references = {}\nhost_templates = {}\nfor connector in connectors_needed:\n    c = next(c for c in active if c[\"connectorName\"] == connector)\n    connection_references[connector] = c.get(\"connectionReferenceTemplate\") or {\n        \"connectionName\": c[\"id\"],   # the connection id from list_live_connections\n        \"source\": \"Invoker\",\n        \"id\": f\"\u002Fproviders\u002FMicrosoft.PowerApps\u002Fapis\u002F{connector}\"\n    }\n    host_templates[connector] = c.get(\"hostTemplate\") or {\n        \"connectionName\": connector\n    }\n```\n\nIn Step 3 action JSON, `inputs.host.connectionName` must be the map key such as\n`shared_teams`, not the GUID. The GUID belongs only inside the\n`connectionReferences[connector].connectionName` value. If an existing flow uses\nthe same connectors, you may also copy its `properties.connectionReferences`\nfrom `get_live_flow`.\n\n---\n\n## 3. Build the Flow Definition\n\nConstruct the definition object. See [flow-schema.md](references\u002Fflow-schema.md)\nfor the full schema and these action pattern references for copy-paste templates:\n- [action-patterns-core.md](references\u002Faction-patterns-core.md) — Variables, control flow, expressions\n- [action-patterns-data.md](references\u002Faction-patterns-data.md) — Array transforms, HTTP, parsing\n- [action-patterns-connectors.md](references\u002Faction-patterns-connectors.md) — SharePoint, Outlook, Teams, Approvals\n\n```python\ndefinition = {\n    \"$schema\": \"https:\u002F\u002Fschema.management.azure.com\u002Fproviders\u002FMicrosoft.Logic\u002Fschemas\u002F2016-06-01\u002Fworkflowdefinition.json#\",\n    \"contentVersion\": \"1.0.0.0\",\n    \"triggers\": { ... },   # see trigger-types.md \u002F build-patterns.md\n    \"actions\": { ... }     # see ACTION-PATTERNS-*.md \u002F build-patterns.md\n}\n```\n\n> See [build-patterns.md](references\u002Fbuild-patterns.md) for complete, ready-to-use\n> flow definitions covering Recurrence+SharePoint+Teams, HTTP triggers, and more.\n\n### Discover connector operations before guessing JSON\n\nFor connector-backed triggers\u002Factions, prefer the live connector describer over\nhand-written shapes. It can return authored hints, canonical examples, variant\nkeys, inputs\u002Foutputs, and dynamic metadata pointers.\n\n```python\n# Search across connectors when you know the user's intent but not the API.\nmatches = mcp(\"describe_live_connector\",\n    environmentName=ENV,\n    search=\"send email\",\n    top=5)\n\n# Describe a specific operation before copying an exampleDefinition.\nop = mcp(\"describe_live_connector\",\n    environmentName=ENV,\n    connectorName=\"shared_office365\",\n    operationId=\"SendEmailV2\")\nprint(op.get(\"hint\"))\n```\n\nWhen an operation has multiple authored variants, request the variant the flow\nneeds:\n\n```python\nteams_chat = mcp(\"describe_live_connector\",\n    environmentName=ENV,\n    connectorName=\"shared_teams\",\n    operationId=\"PostMessageToConversation\",\n    variant=\"flowbot_chat\")\n```\n\nWhen the operation description says a parameter has dynamic options or dynamic\nproperties, call the indicated next tool:\n\n```python\nsp_op = mcp(\"describe_live_connector\",\n    environmentName=ENV,\n    connectorName=\"shared_sharepointonline\",\n    operationId=\"GetItems\")\n\nsites = mcp(\"get_live_dynamic_options\",\n    environmentName=ENV,\n    connectorName=\"shared_sharepointonline\",\n    connectionName=conn_map[\"shared_sharepointonline\"],\n    operationId=\"GetItems\",\n    parameterName=\"dataset\",\n    dynamicMetadata=sp_op[\"dynamicParameters\"][\"dataset\"])\n\nfields = mcp(\"get_live_dynamic_properties\",\n    environmentName=ENV,\n    connectorName=\"shared_sharepointonline\",\n    connectionName=conn_map[\"shared_sharepointonline\"],\n    operationId=\"GetItems\",\n    parameterName=\"item\",\n    parameters={\"dataset\": \"\u003Csite-url>\", \"table\": \"\u003Clist-id>\"},\n    dynamicMetadata=sp_op[\"dynamicProperties\"][\"item\"])\n```\n\nUse dynamic options for dropdown IDs such as SharePoint sites\u002Flists and Teams\nteams\u002Fchannels. Use dynamic properties for schema\u002Ffield shapes such as\nSharePoint list item columns.\n\n---\n\n## 4. Deploy (Create or Update)\n\n`update_live_flow` handles both creation and updates in a single tool.\n\n### Create a new flow (no existing flow)\n\nOmit `flowName` — the server generates a new GUID and creates via PUT:\n\n```python\ndefinition[\"description\"] = \"Weekly SharePoint → Teams notification flow, built by agent\"\n\nresult = mcp(\"update_live_flow\",\n    environmentName=ENV,\n    # flowName omitted → creates a new flow\n    definition=definition,\n    connectionReferences=connection_references,\n    displayName=\"Overdue Invoice Notifications\"\n)\n\nif result.get(\"error\") is not None:\n    print(\"Create failed:\", result[\"error\"])\nelse:\n    # Capture the new flow ID for subsequent steps\n    FLOW_ID = result[\"created\"]\n    print(f\"✅ Flow created: {FLOW_ID}\")\n```\n\n### Update an existing flow\n\nProvide `flowName` to PATCH:\n\n```python\ndefinition[\"description\"] = (\n    \"Updated by agent on \" + __import__('datetime').datetime.utcnow().isoformat()\n)\n\nresult = mcp(\"update_live_flow\",\n    environmentName=ENV,\n    flowName=FLOW_ID,\n    definition=definition,\n    connectionReferences=connection_references,\n    displayName=\"My Updated Flow\"\n)\n\nif result.get(\"error\") is not None:\n    print(\"Update failed:\", result[\"error\"])\nelse:\n    print(\"Update succeeded:\", result)\n```\n\n> ⚠️ `update_live_flow` always returns an `error` key.\n> `null` (Python `None`) means success — do not treat the presence of the key as failure.\n>\n> ⚠️ Flow description lives at `definition[\"description\"]`. The current server\n> appends `#flowstudio-mcp` for usage tracking. Do not pass a top-level\n> `description` argument unless `tool_search` shows one in the active schema.\n\n### Common deployment errors\n\n| Error message (contains) | Cause | Fix |\n|---|---|---|\n| `missing from connectionReferences` | An action's `host.connectionName` references a key that doesn't exist in the `connectionReferences` map | Ensure `host.connectionName` uses the **key** from `connectionReferences` (e.g. `shared_teams`), not the raw GUID |\n| `ConnectionAuthorizationFailed` \u002F 403 | The connection GUID belongs to another user or is not authorized | Re-run Step 2a and use a connection owned by the current `x-api-key` user |\n| `InvalidTemplate` \u002F `InvalidDefinition` | Syntax error in the definition JSON | Check `runAfter` chains, expression syntax, and action type spelling |\n| `ConnectionNotConfigured` | A connector action exists but the connection GUID is invalid or expired | Re-check `list_live_connections` for a fresh GUID |\n\n---\n\n## 5. Verify the Deployment\n\n```python\ncheck = mcp(\"get_live_flow\", environmentName=ENV, flowName=FLOW_ID)\n\n# Confirm state\nprint(\"State:\", check[\"properties\"][\"state\"])  # Should be \"Started\"\n# If state is \"Stopped\", use set_live_flow_state — NOT update_live_flow\n# mcp(\"set_live_flow_state\", environmentName=ENV, flowName=FLOW_ID, state=\"Started\")\n\n# Confirm the action we added is there\nacts = check[\"properties\"][\"definition\"][\"actions\"]\nprint(\"Actions:\", list(acts.keys()))\n```\n\n---\n\n## 6. Test the Flow\n\n> **MANDATORY**: Before triggering any test run, **ask the user for confirmation**.\n> Running a flow has real side effects — it may send emails, post Teams messages,\n> write to SharePoint, start approvals, or call external APIs. Explain what the\n> flow will do and wait for explicit approval before calling `trigger_live_flow`\n> or `resubmit_live_flow_run`.\n\n### Updated flows (have prior runs) — ANY trigger type\n\n> **Use `resubmit_live_flow_run` first.** It works for EVERY trigger type —\n> Recurrence, SharePoint, connector webhooks, Button, and HTTP. It replays\n> the original trigger payload. Do NOT ask the user to manually trigger the\n> flow or wait for the next scheduled run.\n\n```python\nruns = mcp(\"get_live_flow_runs\", environmentName=ENV, flowName=FLOW_ID, top=1)\nif runs:\n    # Works for Recurrence, SharePoint, connector triggers — not just HTTP\n    result = mcp(\"resubmit_live_flow_run\",\n        environmentName=ENV, flowName=FLOW_ID, runName=runs[0][\"name\"])\n    print(result)   # {\"resubmitted\": true, \"triggerName\": \"...\"}\n```\n\n### HTTP, Button, and PowerApps flows — custom test payload\n\nOnly use `trigger_live_flow` when you need to send a **different** payload\nthan the original run. For verifying a fix, `resubmit_live_flow_run` is\nbetter because it uses the exact data that caused the failure.\n\n```python\ndefn = mcp(\"get_live_flow\", environmentName=ENV, flowName=FLOW_ID)\ntriggers = defn[\"properties\"][\"definition\"][\"triggers\"]\nmanual = next(iter(triggers.values()))\nprint(\"Expected body:\", manual.get(\"inputs\", {}).get(\"schema\"))\n\nresult = mcp(\"trigger_live_flow\",\n    environmentName=ENV, flowName=FLOW_ID,\n    body={\"name\": \"Test\", \"value\": 1})\nprint(f\"Status: {result['responseStatus']}, via: {result['invocation']}\")\nprint(result.get(\"warning\"))   # set when a required input was missing: the run still ran, with null\n```\n\n### Brand-new non-HTTP flows\n\nA brand-new **Recurrence** flow needs no workaround: deploy it, then run it\nimmediately with `trigger_live_flow` and no `body` — same as the portal's\n\"Run flow\" button. A body is refused; scheduled triggers take no inputs.\n\nA brand-new **connector-triggered** flow (SharePoint, webhooks) has no prior\nruns and cannot fire without a real source event. Deploy with a temporary\nHTTP trigger, test the actions, then swap to the production trigger:\n\n```python\nproduction_trigger = definition[\"triggers\"]\ndefinition[\"triggers\"] = {\n    \"manual\": {\"type\": \"Request\", \"kind\": \"Http\", \"inputs\": {\"schema\": {}}}\n}\nresult = mcp(\"update_live_flow\", environmentName=ENV,\n    flowName=FLOW_ID,       # omit if creating new\n    definition=definition, connectionReferences=connection_references,\n    displayName=\"Overdue Invoice Notifications\")\nFLOW_ID = FLOW_ID or result[\"flowName\"]\n\nmcp(\"trigger_live_flow\", environmentName=ENV, flowName=FLOW_ID,\n    body={\"sample\": \"payload\"})\nruns = mcp(\"get_live_flow_runs\", environmentName=ENV, flowName=FLOW_ID, top=1)\nif runs[0][\"status\"] == \"Failed\":\n    err = mcp(\"get_live_flow_run_error\",\n        environmentName=ENV, flowName=FLOW_ID, runName=runs[0][\"name\"])\n    raise Exception(err[\"failedActions\"][-1])\n\ndefinition[\"triggers\"] = production_trigger\nmcp(\"update_live_flow\", environmentName=ENV, flowName=FLOW_ID,\n    definition=definition, connectionReferences=connection_references)\n```\n\nThe trigger is only the entry point; testing through HTTP still exercises the\nsame actions. If actions use `triggerBody()` or `triggerOutputs()`, pass a\nrepresentative `body` shaped like the production trigger payload.\n\n---\n\n## Gotchas\n\n| Mistake | Consequence | Prevention |\n|---|---|---|\n| Missing `connectionReferences` in deploy | 400 \"Supply connectionReferences\" | Always call `list_live_connections` first |\n| `\"operationOptions\"` missing on Foreach | Parallel execution, race conditions on writes | Always add `\"Sequential\"` |\n| `union(old_data, new_data)` | Old values override new (first-wins) | Use `union(new_data, old_data)` |\n| `split()` on potentially-null string | `InvalidTemplate` crash | Wrap with `coalesce(field, '')` |\n| Checking `result[\"error\"]` exists | Always present; true error is `!= null` | Use `result.get(\"error\") is not None` |\n| 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 |\n| Teams \"Chat with Flow bot\" recipient as object | 400 `GraphUserDetailNotFound` | Use plain string with trailing semicolon (see below) |\n| Copilot\u002FSkills flow not in a solution | Copilot Studio may not discover it as an agent tool | After deploy, call `add_live_flow_to_solution` with the target `solutionId` |\n| Button\u002FSkills trigger used for MCP testing | Runs even when a required input is missing (null) | Pass inputs in `trigger_live_flow` `body`; on `warning`, cancel and retry with the full body |\n| Connector action missing `metadata.operationMetadataId` | Designer\u002Frun-only UI can behave inconsistently | Preserve existing IDs; add stable GUIDs for new connector actions |\n| Placeholder Excel `scriptId` | Dynamic validation fails at save time | Resolve the real Office Script ID before deploying |\n| SharePoint `PatchItem` omits required fields | Save can fail even if the field is not changing | Echo unchanged required fields such as `item\u002FTitle` |\n| Copilot Studio connector calls a draft agent | Connector invocation can fail or hit stale behavior | Publish the agent before testing\u002Fresubmitting the flow |\n\n### Teams `PostMessageToConversation` — Recipient Formats\n\nThe `body\u002Frecipient` parameter format depends on the `location` value:\n\n| Location | `body\u002Frecipient` format | Example |\n|---|---|---|\n| **Chat with Flow bot** | Plain email string with **trailing semicolon** | `\"user@contoso.com;\"` |\n| **Channel** | Object with `groupId` and `channelId` | `{\"groupId\": \"...\", \"channelId\": \"...\"}` |\n\n> **Common mistake**: passing `{\"to\": \"user@contoso.com\"}` for \"Chat with Flow bot\"\n> returns a 400 `GraphUserDetailNotFound` error. The API expects a plain string.\n\n---\n\n## Reference Files\n\n- [flow-schema.md](references\u002Fflow-schema.md) — Full flow definition JSON schema\n- [trigger-types.md](references\u002Ftrigger-types.md) — Trigger type templates\n- [action-patterns-core.md](references\u002Faction-patterns-core.md) — Variables, control flow, expressions\n- [action-patterns-data.md](references\u002Faction-patterns-data.md) — Array transforms, HTTP, parsing\n- [action-patterns-connectors.md](references\u002Faction-patterns-connectors.md) — SharePoint, Outlook, Teams, Approvals\n- [build-patterns.md](references\u002Fbuild-patterns.md) — Complete flow definition templates (Recurrence+SP+Teams, HTTP trigger)\n\n## Related Skills\n\n- `power-automate-mcp` — Core connection setup and tool reference\n- `power-automate-debug` — Debug failing flows after deployment\n",{"name":5,"description":7},"main","2b63f856ce19c2a797929cacabd9e0fc936812fa","plugins\u002Fninihen1\u002Fpower-automate-mcp-skills\u002Fskills\u002Fpower-automate-build",490,"https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins","https:\u002F\u002Fhol.org\u002Fplugins\u002Fbest-codex-plugins","https:\u002F\u002Fgithub.com\u002Fhashgraph-online","https:\u002F\u002Fhol.org","Open-source standards and developer tools for interoperable AI agents: discovery, identity, communication, payments, privacy and security.","2026-11-14 02:12:02",{"source":8,"skillName":5,"commands":65,"prompt":75,"zipAvailable":76},[66,69,72],{"tool":67,"command":68},"npx","npx skills add hashgraph-online\u002Fawesome-codex-plugins --skill power-automate-build",{"tool":70,"command":71},"bunx","bunx skills add hashgraph-online\u002Fawesome-codex-plugins --skill power-automate-build",{"tool":73,"command":74},"pnpm","pnpm dlx skills add hashgraph-online\u002Fawesome-codex-plugins --skill power-automate-build","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fninihen1\u002Fpower-automate-mcp-skills\u002Fskills\u002Fpower-automate-build\u002FSKILL.md",true,[78,84,88,92,96,100],{"path":79,"resourceType":80,"resourceTypeDesc":81,"sizeBytes":82,"sourceHtmlUrl":83},"references\u002Faction-patterns-connectors.md","REFERENCE","参考文档",18400,"https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fninihen1\u002Fpower-automate-mcp-skills\u002Fskills\u002Fpower-automate-build\u002Freferences\u002Faction-patterns-connectors.md",{"path":85,"resourceType":80,"resourceTypeDesc":81,"sizeBytes":86,"sourceHtmlUrl":87},"references\u002Faction-patterns-core.md",16611,"https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fninihen1\u002Fpower-automate-mcp-skills\u002Fskills\u002Fpower-automate-build\u002Freferences\u002Faction-patterns-core.md",{"path":89,"resourceType":80,"resourceTypeDesc":81,"sizeBytes":90,"sourceHtmlUrl":91},"references\u002Faction-patterns-data.md",19019,"https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fninihen1\u002Fpower-automate-mcp-skills\u002Fskills\u002Fpower-automate-build\u002Freferences\u002Faction-patterns-data.md",{"path":93,"resourceType":80,"resourceTypeDesc":81,"sizeBytes":94,"sourceHtmlUrl":95},"references\u002Fbuild-patterns.md",2726,"https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fninihen1\u002Fpower-automate-mcp-skills\u002Fskills\u002Fpower-automate-build\u002Freferences\u002Fbuild-patterns.md",{"path":97,"resourceType":80,"resourceTypeDesc":81,"sizeBytes":98,"sourceHtmlUrl":99},"references\u002Fflow-schema.md",5208,"https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fninihen1\u002Fpower-automate-mcp-skills\u002Fskills\u002Fpower-automate-build\u002Freferences\u002Fflow-schema.md",{"path":101,"resourceType":80,"resourceTypeDesc":81,"sizeBytes":102,"sourceHtmlUrl":103},"references\u002Ftrigger-types.md",5463,"https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fninihen1\u002Fpower-automate-mcp-skills\u002Fskills\u002Fpower-automate-build\u002Freferences\u002Ftrigger-types.md",[105,113,120,127,153,178],{"skillNo":106,"name":107,"nameZh":6,"description":108,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":109,"categories":110,"keywords":111,"publishedAt":112},"01M746ZWACVKMZ1BJXJZHYJSSX","migrate-to-e2e","Moves an existing Playwright, Cypress, Selenium, Appium, Detox, Maestro, or TesterArmy suite to e2e one slice at a time, with the old suite running beside the new one until each ported test is proven. Keeps a MIGRATION.md progress file so any later session resumes where the last stopped. Optionally plants a defect to show both suites catch it. Use for \u002Fmigrate-to-e2e, \"migrate our tests to e2e\", \"port these Maestro flows\", \"move our TesterArmy tests\", or when a project has an e2e config and an older suite still running.","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Ftester-army\u002Fe2e\u002Fskills\u002Fmigrate-to-e2e\u002FSKILL.md",[],[],"2026-11-11 15:11:14",{"skillNo":114,"name":115,"nameZh":6,"description":116,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":117,"categories":118,"keywords":119,"publishedAt":112},"01M746ZPTAX1Q0FBKAB1CYND7E","e2e","Writes, runs, and debugs end-to-end tests for web and mobile apps with e2e, the agentic test runner, which mixes agent.act goals with exact locator assertions on a Playwright browser or an iOS or Android device. Also drives a project's running app live over the e2e MCP server to look at a screen, check a UI change, take a screenshot or record a video, and try a locator; and runs bug bashes, parallel e2e explore runs with each bug proven by a repro test. Use when a project depends on e2e or has an e2e.config.ts, when asked for end-to-end, browser, mobile, or agentic UI tests, to check a change in the running app, to QA or bug bash an app or branch, or when an e2e run fails.","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Ftester-army\u002Fe2e\u002Fskills\u002Fe2e\u002FSKILL.md",[],[],{"skillNo":121,"name":122,"nameZh":6,"description":123,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":124,"categories":125,"keywords":126,"publishedAt":112},"01M746ZJN784HVHMDP9MQGCSGG","create-verification-skill","Generate a project-local verify-\u003Capp> skill on top of e2e, so any coding agent can launch the app, check it is worth driving, exercise a feature the way a user does, keep evidence, and bug bash it. Writes the skill, a feature map with one explore charter per feature, and proves it once. Use for \u002Fcreate-verification-skill, \"make a verification skill for this repo\", or when a project has no scripted way to prove UI behavior.","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Ftester-army\u002Fe2e\u002Fskills\u002Fcreate-verification-skill\u002FSKILL.md",[],[],{"skillNo":128,"name":129,"nameZh":6,"description":130,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":131,"categories":132,"keywords":133,"publishedAt":49},"01M716A6ETNB9B1SQ3GXZC75VR","deja-search","deja-vu memory — search the user's past AI coding sessions with the deja CLI. Holds what they already settled and never wrote into the repo (naming rules, banned or already-tried tools, required checks before merge, preferred values, who owns what). Use before your first edit in a task, before you call a change done or ready to merge, before you recommend a tool, library, design or reviewer, before re-debugging an error that may already be solved, when they say 'didn't we fix this before', 'what did we decide about X' or 'I already have that', and before telling them something on this machine does not exist.","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fvshulcz\u002Fdeja-vu\u002Fskills\u002Fdeja-search\u002FSKILL.md",[],[134,135,136,137,138,139,140,141,142,143,144,33,145,146,147,148,149,150,151,152],"search","deja search","never","error","ready","memory","re","decide","fix","design","debugging","you","done","reviewer","io","change","cli","merge","past",{"skillNo":154,"name":155,"nameZh":6,"description":156,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":157,"categories":158,"keywords":159,"publishedAt":49},"01M716A3J2W5SENSE9VGMXB375","deja-reflect","End-of-session reflection and memory curation with deja-vu. Review what was decided, what commands broke and what repaired them, and record durable project rules or decisions with deja remember so the next session starts with them.","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fvshulcz\u002Fdeja-vu\u002Fskills\u002Fdeja-reflect\u002FSKILL.md",[],[160,161,162,148,163,164,165,166,167,168,169,170,171,172,139,173,174,175,176,177],"deja reflect","reflect","review","with","record","github","next","https","node","Rules","decisions","brew","remember","project rules","project","session","end","reflection",{"skillNo":179,"name":180,"nameZh":6,"description":181,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":182,"categories":183,"keywords":191,"publishedAt":49},"01M715T3RR4BAYSR57HPPTJ0PF","revid","Make, edit, export and post AI videos with Revid (revid.ai) through the Revid MCP server. Use whenever the user wants a short-form or long-form video made (from an idea, a script, a URL, an article, a PDF, a tweet, a product page, their own clips, or a song), wants to find what is going viral on TikTok, YouTube, Instagram or X before making something, wants to edit or re-export an existing Revid project, generate a standalone AI image or clip, make a series episode, or publish and schedule a finished video to connected social accounts. Covers setup (hosted MCP with OAuth, or an API key), the 36 tools, credits, polling and the rules for publishing. Routes to the more specific revid-* skills when one fits.","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Ftmakersas\u002Frevid-skills\u002Fskills\u002Frevid\u002FSKILL.md",[184,187,188],{"categoryNo":185,"categoryName":186,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000016","图像与多媒体",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":189,"categoryName":190,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口",[180,192,193,194,195,196,197,174,198,140,199,200,40,201,33,202,48,203,204,205],"URL","Video","short-form","standalone","PDF","viral","tiktok","short","social","song","image","schedule","api","publish"]