flowstudio-power-automate-build

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Build & Deploy Power Automate Flows with FlowStudio MCP

使用FlowStudio MCP构建并部署Power Automate流

Step-by-step guide for constructing and deploying Power Automate cloud flows programmatically through the FlowStudio MCP server.
Prerequisite: A FlowStudio MCP server must be reachable with a valid JWT. See the
flowstudio-power-automate-mcp
skill for connection setup.
Subscribe at https://mcp.flowstudio.app

通过FlowStudio MCP服务器以编程方式构建和部署Power Automate云流的分步指南。
前提条件:必须能够访问带有有效JWT的FlowStudio MCP服务器。 请查看
flowstudio-power-automate-mcp
技能了解连接设置。 订阅地址:https://mcp.flowstudio.app

Source of Truth

权威参考

Always call
tools/list
first
to confirm available tool names and their parameter schemas. Tool names and parameters may change between server versions. This skill covers response shapes, behavioral notes, and build patterns — things
tools/list
cannot tell you. If this document disagrees with
tools/list
or a real API response, the API wins.

请始终先调用
tools/list
,确认可用工具名称及其参数架构。工具名称和参数可能会随服务器版本变化。 本技能涵盖响应格式、行为说明和构建模式——这些是
tools/list
无法提供的信息。如果本文档与
tools/list
或实际API响应存在冲突,以API为准。

Python Helper

Python辅助工具

python
import json, urllib.request

MCP_URL   = "https://mcp.flowstudio.app/mcp"
MCP_TOKEN = "<YOUR_JWT_TOKEN>"

def mcp(tool, **kwargs):
    payload = json.dumps({"jsonrpc": "2.0", "id": 1, "method": "tools/call",
                          "params": {"name": tool, "arguments": kwargs}}).encode()
    req = urllib.request.Request(MCP_URL, data=payload,
        headers={"x-api-key": MCP_TOKEN, "Content-Type": "application/json",
                 "User-Agent": "FlowStudio-MCP/1.0"})
    try:
        resp = urllib.request.urlopen(req, timeout=120)
    except urllib.error.HTTPError as e:
        body = e.read().decode("utf-8", errors="replace")
        raise RuntimeError(f"MCP HTTP {e.code}: {body[:200]}") from e
    raw = json.loads(resp.read())
    if "error" in raw:
        raise RuntimeError(f"MCP error: {json.dumps(raw['error'])}")
    return json.loads(raw["result"]["content"][0]["text"])

ENV = "<environment-id>"  # e.g. Default-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

python
import json, urllib.request

MCP_URL   = "https://mcp.flowstudio.app/mcp"
MCP_TOKEN = "<YOUR_JWT_TOKEN>"

def mcp(tool, **kwargs):
    payload = json.dumps({"jsonrpc": "2.0", "id": 1, "method": "tools/call",
                          "params": {"name": tool, "arguments": kwargs}}).encode()
    req = urllib.request.Request(MCP_URL, data=payload,
        headers={"x-api-key": MCP_TOKEN, "Content-Type": "application/json",
                 "User-Agent": "FlowStudio-MCP/1.0"})
    try:
        resp = urllib.request.urlopen(req, timeout=120)
    except urllib.error.HTTPError as e:
        body = e.read().decode("utf-8", errors="replace")
        raise RuntimeError(f"MCP HTTP {e.code}: {body[:200]}") from e
    raw = json.loads(resp.read())
    if "error" in raw:
        raise RuntimeError(f"MCP error: {json.dumps(raw['error'])}")
    return json.loads(raw["result"]["content"][0]["text"])

ENV = "<environment-id>"  # 示例:Default-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Step 1 — Safety Check: Does the Flow Already Exist?

步骤1 — 安全检查:流是否已存在?

Always look before you build to avoid duplicates:
python
results = mcp("list_store_flows",
    environmentName=ENV, searchTerm="My New Flow")
在构建前务必先确认,避免重复创建:
python
results = mcp("list_store_flows",
    environmentName=ENV, searchTerm="My New Flow")

list_store_flows returns a direct array (no wrapper object)

list_store_flows直接返回数组(无包装对象)

if len(results) > 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] print(f"Existing flow: {FLOW_ID}") defn = mcp("get_live_flow", environmentName=ENV, flowName=FLOW_ID) else: print("Flow not found — building from scratch") FLOW_ID = None

---
if len(results) > 0: # 流已存在——选择修改而非创建 # id格式为"envId.flowId"——拆分以获取流UUID FLOW_ID = results[0]["id"].split(".", 1)[1] print(f"已存在的流:{FLOW_ID}") defn = mcp("get_live_flow", environmentName=ENV, flowName=FLOW_ID) else: print("未找到流——从头开始构建") FLOW_ID = None

---

Step 2 — Obtain Connection References

步骤2 — 获取连接引用

Every connector action needs a
connectionName
that points to a key in the flow's
connectionReferences
map. That key links to an authenticated connection in the environment.
MANDATORY: You MUST call
list_live_connections
first — do NOT ask the user for connection names or GUIDs. The API returns the exact values you need. Only prompt the user if the API confirms that required connections are missing.
每个连接器操作都需要一个
connectionName
,指向流的
connectionReferences
映射中的键。该键关联环境中的已认证连接。
强制要求:必须先调用
list_live_connections
——不要向用户索要连接名称或GUID。API会返回你所需的准确值。只有当API确认缺少必要连接时,才向用户提示。

2a — Always call
list_live_connections
first

2a — 始终先调用
list_live_connections

python
conns = mcp("list_live_connections", environmentName=ENV)
python
conns = mcp("list_live_connections", environmentName=ENV)

Filter to connected (authenticated) connections only

仅筛选已连接(已认证)的连接

active = [c for c in conns["connections"] if c["statuses"][0]["status"] == "Connected"]
active = [c for c in conns["connections"] if c["statuses"][0]["status"] == "Connected"]

Build a lookup: connectorName → connectionName (id)

构建查找表:connectorName → connectionName(id)

conn_map = {} for c in active: conn_map[c["connectorName"]] = c["id"]
print(f"Found {len(active)} active connections") print("Available connectors:", list(conn_map.keys()))
undefined
conn_map = {} for c in active: conn_map[c["connectorName"]] = c["id"]
print(f"找到{len(active)}个活跃连接") print("可用连接器:", list(conn_map.keys()))
undefined

2b — Determine which connectors the flow needs

2b — 确定流所需的连接器

Based on the flow you are building, identify which connectors are required. Common connector API names:
ConnectorAPI name
SharePoint
shared_sharepointonline
Outlook / Office 365
shared_office365
Teams
shared_teams
Approvals
shared_approvals
OneDrive for Business
shared_onedriveforbusiness
Excel Online (Business)
shared_excelonlinebusiness
Dataverse
shared_commondataserviceforapps
Microsoft Forms
shared_microsoftforms
Flows that need NO connections (e.g. Recurrence + Compose + HTTP only) can skip the rest of Step 2 — omit
connectionReferences
from the deploy call.
根据要构建的流,确定所需的连接器。常见连接器API名称:
连接器API名称
SharePoint
shared_sharepointonline
Outlook / Office 365
shared_office365
Teams
shared_teams
审批
shared_approvals
OneDrive for Business
shared_onedriveforbusiness
Excel Online (Business)
shared_excelonlinebusiness
Dataverse
shared_commondataserviceforapps
Microsoft Forms
shared_microsoftforms
无需连接的流(例如仅包含Recurrence、Compose和HTTP的流)可以跳过步骤2的剩余部分——在部署调用中省略
connectionReferences

2c — If connections are missing, guide the user

2c — 如果缺少连接,引导用户

python
connectors_needed = ["shared_sharepointonline", "shared_office365"]  # adjust per flow

missing = [c for c in connectors_needed if c not in conn_map]

if not missing:
    print("✅ All required connections are available — proceeding to build")
else:
    # ── STOP: connections must be created interactively ──
    # Connections require OAuth consent in a browser — no API can create them.
    print("⚠️  The following connectors have no active connection in this environment:")
    for c in missing:
        friendly = c.replace("shared_", "").replace("onlinebusiness", " Online (Business)")
        print(f"   • {friendly}  (API name: {c})")
    print()
    print("Please create the missing connections:")
    print("  1. Open https://make.powerautomate.com/connections")
    print("  2. Select the correct environment from the top-right picker")
    print("  3. Click '+ New connection' for each missing connector listed above")
    print("  4. Sign in and authorize when prompted")
    print("  5. Tell me when done — I will re-check and continue building")
    # DO NOT proceed to Step 3 until the user confirms.
    # After user confirms, re-run Step 2a to refresh conn_map.
python
connectors_needed = ["shared_sharepointonline", "shared_office365"]  # 根据流调整

missing = [c for c in connectors_needed if c not in conn_map]

if not missing:
    print("✅ 所有必要连接均可用——继续构建")
else:
    # ── 停止:连接必须交互式创建 ──
    # 连接需要在浏览器中进行OAuth授权——无法通过API创建。
    print("⚠️  此环境中缺少以下连接器的活跃连接:")
    for c in missing:
        friendly = c.replace("shared_", "").replace("onlinebusiness", " Online (Business)")
        print(f"   • {friendly} (API名称:{c})")
    print()
    print("请创建缺少的连接:")
    print("  1. 打开https://make.powerautomate.com/connections")
    print("  2. 从右上角选择器中选择正确的环境")
    print("  3. 为上述每个缺少的连接器点击'+ 新建连接'")
    print("  4. 登录并按提示授权")
    print("  5. 完成后告知我——我将重新检查并继续构建")
    # 在用户确认前不要进行步骤3。
    # 用户确认后,重新运行步骤2a以刷新conn_map。

2d — Build the connectionReferences block

2d — 构建connectionReferences块

Only execute this after 2c confirms no missing connectors:
python
connection_references = {}
for connector in connectors_needed:
    connection_references[connector] = {
        "connectionName": conn_map[connector],   # the GUID from list_live_connections
        "source": "Invoker",
        "id": f"/providers/Microsoft.PowerApps/apis/{connector}"
    }
IMPORTANT —
host.connectionName
in actions
: When building actions in Step 3, set
host.connectionName
to the key from this map (e.g.
shared_teams
), NOT the connection GUID. The GUID only goes inside the
connectionReferences
entry. The engine matches the action's
host.connectionName
to the key to find the right connection.
Alternative — if you already have a flow using the same connectors, you can extract
connectionReferences
from its definition:
python
ref_flow = mcp("get_live_flow", environmentName=ENV, flowName="<existing-flow-id>")
connection_references = ref_flow["properties"]["connectionReferences"]
See the
power-automate-mcp
skill's connection-references.md reference for the full connection reference structure.

仅在2c确认无缺失连接器后执行:
python
connection_references = {}
for connector in connectors_needed:
    connection_references[connector] = {
        "connectionName": conn_map[connector],   # 来自list_live_connections的GUID
        "source": "Invoker",
        "id": f"/providers/Microsoft.PowerApps/apis/{connector}"
    }
重要提示——操作中的
host.connectionName
:在步骤3中构建操作时,将
host.connectionName
设置为此映射中的(例如
shared_teams
),而非连接GUID。GUID仅在
connectionReferences
条目中使用。引擎会将操作的
host.connectionName
与键匹配,以找到正确的连接。
替代方案——如果你已有使用相同连接器的流,可以从其定义中提取
connectionReferences
python
ref_flow = mcp("get_live_flow", environmentName=ENV, flowName="<existing-flow-id>")
connection_references = ref_flow["properties"]["connectionReferences"]
请查看
power-automate-mcp
技能的connection-references.md参考文档,了解完整的连接引用结构。

Step 3 — Build the Flow Definition

步骤3 — 构建流定义

Construct the definition object. See flow-schema.md for the full schema and these action pattern references for copy-paste templates:
  • action-patterns-core.md — Variables, control flow, expressions
  • action-patterns-data.md — Array transforms, HTTP, parsing
  • action-patterns-connectors.md — SharePoint, Outlook, Teams, Approvals
python
definition = {
    "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
    "contentVersion": "1.0.0.0",
    "triggers": { ... },   # see trigger-types.md / build-patterns.md
    "actions": { ... }     # see ACTION-PATTERNS-*.md / build-patterns.md
}
See build-patterns.md for complete, ready-to-use flow definitions covering Recurrence+SharePoint+Teams, HTTP triggers, and more.

构造定义对象。完整架构请参见flow-schema.md,以下操作模式参考提供了可直接复制的模板:
  • action-patterns-core.md — 变量、控制流、表达式
  • action-patterns-data.md — 数组转换、HTTP、解析
  • action-patterns-connectors.md — SharePoint、Outlook、Teams、审批
python
definition = {
    "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
    "contentVersion": "1.0.0.0",
    "triggers": { ... },   # 请查看trigger-types.md / build-patterns.md
    "actions": { ... }     # 请查看ACTION-PATTERNS-*.md / build-patterns.md
}
完整的即用型流定义请参见build-patterns.md,包括Recurrence+SharePoint+Teams、HTTP触发器等场景。

Step 4 — Deploy (Create or Update)

步骤4 — 部署(创建或更新)

update_live_flow
handles both creation and updates in a single tool.
update_live_flow
可同时处理创建和更新操作。

Create a new flow (no existing flow)

创建新流(无现有流)

Omit
flowName
— the server generates a new GUID and creates via PUT:
python
result = mcp("update_live_flow",
    environmentName=ENV,
    # flowName omitted → creates a new flow
    definition=definition,
    connectionReferences=connection_references,
    displayName="Overdue Invoice Notifications",
    description="Weekly SharePoint → Teams notification flow, built by agent"
)

if result.get("error") is not None:
    print("Create failed:", result["error"])
else:
    # Capture the new flow ID for subsequent steps
    FLOW_ID = result["created"]
    print(f"✅ Flow created: {FLOW_ID}")
省略
flowName
——服务器会生成新的GUID并通过PUT请求创建:
python
result = mcp("update_live_flow",
    environmentName=ENV,
    # 省略flowName → 创建新流
    definition=definition,
    connectionReferences=connection_references,
    displayName="逾期发票通知",
    description="每周SharePoint → Teams通知流,由agent构建"
)

if result.get("error") is not None:
    print("创建失败:", result["error"])
else:
    # 捕获新流ID用于后续步骤
    FLOW_ID = result["created"]
    print(f"✅ 流已创建:{FLOW_ID}")

Update an existing flow

更新现有流

Provide
flowName
to PATCH:
python
result = mcp("update_live_flow",
    environmentName=ENV,
    flowName=FLOW_ID,
    definition=definition,
    connectionReferences=connection_references,
    displayName="My Updated Flow",
    description="Updated by agent on " + __import__('datetime').datetime.utcnow().isoformat()
)

if result.get("error") is not None:
    print("Update failed:", result["error"])
else:
    print("Update succeeded:", result)
⚠️
update_live_flow
always returns an
error
key.
null
(Python
None
) means success — do not treat the presence of the key as failure.
⚠️
description
is required for both create and update.
提供
flowName
以执行PATCH请求:
python
result = mcp("update_live_flow",
    environmentName=ENV,
    flowName=FLOW_ID,
    definition=definition,
    connectionReferences=connection_references,
    displayName="我的更新流",
    description="由agent于" + __import__('datetime').datetime.utcnow().isoformat() + "更新"
)

if result.get("error") is not None:
    print("更新失败:", result["error"])
else:
    print("更新成功:", result)
⚠️
update_live_flow
始终返回
error
键。
null
(Python中的
None
)表示成功——不要仅因键存在就判定为失败。
⚠️
description
在创建和更新操作中都是必填项。

Common deployment errors

常见部署错误

Error message (contains)CauseFix
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
ConnectionAuthorizationFailed
/ 403
The connection GUID belongs to another user or is not authorizedRe-run Step 2a and use a connection owned by the current
x-api-key
user
InvalidTemplate
/
InvalidDefinition
Syntax error in the definition JSONCheck
runAfter
chains, expression syntax, and action type spelling
ConnectionNotConfigured
A connector action exists but the connection GUID is invalid or expiredRe-check
list_live_connections
for a fresh GUID

错误消息(包含)原因修复方法
missing from connectionReferences
操作的
host.connectionName
引用了
connectionReferences
映射中不存在的键
确保
host.connectionName
使用
connectionReferences
中的(例如
shared_teams
),而非原始GUID
ConnectionAuthorizationFailed
/ 403
连接GUID属于其他用户或未授权重新运行步骤2a,使用当前
x-api-key
用户拥有的连接
InvalidTemplate
/
InvalidDefinition
定义JSON存在语法错误检查
runAfter
链、表达式语法和操作类型拼写
ConnectionNotConfigured
存在连接器操作,但连接GUID无效或已过期重新检查
list_live_connections
以获取最新GUID

Step 5 — Verify the Deployment

步骤5 — 验证部署

python
check = mcp("get_live_flow", environmentName=ENV, flowName=FLOW_ID)
python
check = mcp("get_live_flow", environmentName=ENV, flowName=FLOW_ID)

Confirm state

确认状态

print("State:", check["properties"]["state"]) # Should be "Started"
print("状态:", check["properties"]["state"]) # 应为"Started"

Confirm the action we added is there

确认添加的操作已存在

acts = check["properties"]["definition"]["actions"] print("Actions:", list(acts.keys()))

---
acts = check["properties"]["definition"]["actions"] print("操作:", list(acts.keys()))

---

Step 6 — Test the Flow

步骤6 — 测试流

MANDATORY: Before triggering any test run, ask the user for confirmation. Running a flow has real side effects — it may send emails, post Teams messages, write to SharePoint, start approvals, or call external APIs. Explain what the flow will do and wait for explicit approval before calling
trigger_live_flow
or
resubmit_live_flow_run
.
强制要求:在触发任何测试运行前,务必征得用户确认。 运行流会产生实际影响——可能发送邮件、发布Teams消息、写入SharePoint、启动审批或调用外部API。请说明流的具体操作,等待用户明确批准后再调用
trigger_live_flow
resubmit_live_flow_run

Updated flows (have prior runs)

已更新的流(有历史运行记录)

The fastest path — resubmit the most recent run:
python
runs = mcp("get_live_flow_runs", environmentName=ENV, flowName=FLOW_ID, top=1)
if runs:
    result = mcp("resubmit_live_flow_run",
        environmentName=ENV, flowName=FLOW_ID, runName=runs[0]["name"])
    print(result)
最快的方式——重新提交最近一次运行:
python
runs = mcp("get_live_flow_runs", environmentName=ENV, flowName=FLOW_ID, top=1)
if runs:
    result = mcp("resubmit_live_flow_run",
        environmentName=ENV, flowName=FLOW_ID, runName=runs[0]["name"])
    print(result)

Flows already using an HTTP trigger

已使用HTTP触发器的流

Fire directly with a test payload:
python
schema = mcp("get_live_flow_http_schema",
    environmentName=ENV, flowName=FLOW_ID)
print("Expected body:", schema.get("triggerSchema"))

result = mcp("trigger_live_flow",
    environmentName=ENV, flowName=FLOW_ID,
    body={"name": "Test", "value": 1})
print(f"Status: {result['status']}")
直接使用测试负载触发:
python
schema = mcp("get_live_flow_http_schema",
    environmentName=ENV, flowName=FLOW_ID)
print("预期请求体:", schema.get("triggerSchema"))

result = mcp("trigger_live_flow",
    environmentName=ENV, flowName=FLOW_ID,
    body={"name": "Test", "value": 1})
print(f"状态:{result['status']}")

Brand-new non-HTTP flows (Recurrence, connector triggers, etc.)

全新的非HTTP流(Recurrence、连接器触发器等)

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.
全新的Recurrence或连接器触发流没有可重新提交的运行记录,也没有可调用的HTTP端点。先部署临时HTTP触发器,测试操作,再切换为生产触发器。

7a — Save the real trigger, deploy with a temporary HTTP trigger

7a — 保存真实触发器,部署临时HTTP触发器

python
undefined
python
undefined

Save the production trigger you built in Step 3

保存步骤3中构建的生产触发器

production_trigger = definition["triggers"]
production_trigger = definition["triggers"]

Replace with a temporary HTTP trigger

替换为临时HTTP触发器

definition["triggers"] = { "manual": { "type": "Request", "kind": "Http", "inputs": { "schema": {} } } }
definition["triggers"] = { "manual": { "type": "Request", "kind": "Http", "inputs": { "schema": {} } } }

Deploy (create or update) with the temp trigger

部署(创建或更新)临时触发器

result = mcp("update_live_flow", environmentName=ENV, flowName=FLOW_ID, # omit if creating new definition=definition, connectionReferences=connection_references, displayName="Overdue Invoice Notifications", description="Deployed with temp HTTP trigger for testing")
if result.get("error") is not None: print("Deploy failed:", result["error"]) else: if not FLOW_ID: FLOW_ID = result["created"] print(f"✅ Deployed with temp HTTP trigger: {FLOW_ID}")
undefined
result = mcp("update_live_flow", environmentName=ENV, flowName=FLOW_ID, # 创建新流时省略 definition=definition, connectionReferences=connection_references, displayName="逾期发票通知", description="部署临时HTTP触发器用于测试")
if result.get("error") is not None: print("部署失败:", result["error"]) else: if not FLOW_ID: FLOW_ID = result["created"] print(f"✅ 已部署临时HTTP触发器:{FLOW_ID}")
undefined

7b — Fire the flow and check the result

7b — 触发流并检查结果

python
undefined
python
undefined

Trigger the flow

触发流

test = mcp("trigger_live_flow", environmentName=ENV, flowName=FLOW_ID) print(f"Trigger response status: {test['status']}")
test = mcp("trigger_live_flow", environmentName=ENV, flowName=FLOW_ID) print(f"触发响应状态:{test['status']}")

Wait for the run to complete

等待运行完成

import time; time.sleep(15)
import time; time.sleep(15)

Check the run result

检查运行结果

runs = mcp("get_live_flow_runs", environmentName=ENV, flowName=FLOW_ID, top=1) run = runs[0] print(f"Run {run['name']}: {run['status']}")
if run["status"] == "Failed": err = mcp("get_live_flow_run_error", environmentName=ENV, flowName=FLOW_ID, runName=run["name"]) 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
undefined
runs = mcp("get_live_flow_runs", environmentName=ENV, flowName=FLOW_ID, top=1) run = runs[0] print(f"运行{run['name']}:{run['status']}")
if run["status"] == "Failed": err = mcp("get_live_flow_run_error", environmentName=ENV, flowName=FLOW_ID, runName=run["name"]) root = err["failedActions"][-1] print(f"根本原因:{root['actionName']} → {root.get('code')}") # 调试并修复定义后再继续 # 完整诊断流程请查看power-automate-debug技能
undefined

7c — Swap to the production trigger

7c — 切换为生产触发器

Once the test run succeeds, replace the temporary HTTP trigger with the real one:
python
undefined
测试运行成功后,将临时HTTP触发器替换为真实触发器:
python
undefined

Restore the production trigger

恢复生产触发器

definition["triggers"] = production_trigger
result = mcp("update_live_flow", environmentName=ENV, flowName=FLOW_ID, definition=definition, connectionReferences=connection_references, description="Swapped to production trigger after successful test")
if result.get("error") is not None: print("Trigger swap failed:", result["error"]) else: print("✅ Production trigger deployed — flow is live")

> **Why this works**: The trigger is just the entry point — the actions are
> identical regardless of how the flow starts. Testing via HTTP trigger
> exercises all the same Compose, SharePoint, Teams, etc. actions.
>
> **Connector triggers** (e.g. "When an item is created in SharePoint"):
> If actions reference `triggerBody()` or `triggerOutputs()`, pass a
> representative test payload in `trigger_live_flow`'s `body` parameter
> that matches the shape the connector trigger would produce.

---
definition["triggers"] = production_trigger
result = mcp("update_live_flow", environmentName=ENV, flowName=FLOW_ID, definition=definition, connectionReferences=connection_references, description="测试成功后切换为生产触发器")
if result.get("error") is not None: print("触发器切换失败:", result["error"]) else: print("✅ 生产触发器已部署——流已启用")

> **原理**:触发器只是入口点——无论流如何启动,操作都是相同的。通过HTTP触发器测试可以验证所有Compose、SharePoint、Teams等操作。
>
> **连接器触发器**(例如“SharePoint中创建项时”):
> 如果操作引用了`triggerBody()`或`triggerOutputs()`,请在`trigger_live_flow`的`body`参数中传入与连接器触发器输出格式一致的测试负载。

---

Gotchas

注意事项

MistakeConsequencePrevention
Missing
connectionReferences
in deploy
400 "Supply connectionReferences"Always call
list_live_connections
first
"operationOptions"
missing on Foreach
Parallel execution, race conditions on writesAlways add
"Sequential"
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 scheduleCheck connection auth; re-enable
Teams "Chat with Flow bot" recipient as object400
GraphUserDetailNotFound
Use plain string with trailing semicolon (see below)
错误操作后果预防措施
部署时缺少
connectionReferences
400错误“Supply connectionReferences”始终先调用
list_live_connections
Foreach操作中缺少
"operationOptions"
并行执行,写入时出现竞争条件始终添加
"Sequential"
使用
union(old_data, new_data)
旧值覆盖新值(先到先得)使用
union(new_data, old_data)
对可能为空的字符串使用
split()
InvalidTemplate
崩溃
coalesce(field, '')
包裹
检查
result["error"]
是否存在
该键始终存在;真正的错误是
!= null
使用
result.get("error") is not None
流已部署但状态为“Stopped”流不会按计划运行检查连接授权;重新启用流
Teams“Chat with Flow bot”收件人使用对象格式400错误
GraphUserDetailNotFound
使用带末尾分号的纯字符串(见下文)

Teams
PostMessageToConversation
— Recipient Formats

Teams
PostMessageToConversation
— 收件人格式

The
body/recipient
parameter format depends on the
location
value:
Location
body/recipient
format
Example
Chat with Flow botPlain email string with trailing semicolon
"user@contoso.com;"
ChannelObject with
groupId
and
channelId
{"groupId": "...", "channelId": "..."}
Common mistake: passing
{"to": "user@contoso.com"}
for "Chat with Flow bot" returns a 400
GraphUserDetailNotFound
error. The API expects a plain string.

body/recipient
参数格式取决于
location
值:
位置
body/recipient
格式
示例
Chat with Flow bot末尾分号的纯邮箱字符串
"user@contoso.com;"
频道包含
groupId
channelId
的对象
{"groupId": "...", "channelId": "..."}
常见错误:为“Chat with Flow bot”传入
{"to": "user@contoso.com"}
会返回400错误
GraphUserDetailNotFound
。API要求传入纯字符串。

Reference Files

参考文件

  • flow-schema.md — Full flow definition JSON schema
  • trigger-types.md — Trigger type templates
  • action-patterns-core.md — Variables, control flow, expressions
  • action-patterns-data.md — Array transforms, HTTP, parsing
  • action-patterns-connectors.md — SharePoint, Outlook, Teams, Approvals
  • build-patterns.md — Complete flow definition templates (Recurrence+SP+Teams, HTTP trigger)
  • flow-schema.md — 完整的流定义JSON架构
  • trigger-types.md — 触发器类型模板
  • action-patterns-core.md — 变量、控制流、表达式
  • action-patterns-data.md — 数组转换、HTTP、解析
  • action-patterns-connectors.md — SharePoint、Outlook、Teams、审批
  • build-patterns.md — 完整的流定义模板(Recurrence+SP+Teams、HTTP触发器)

Related Skills

相关技能

  • flowstudio-power-automate-mcp
    — Core connection setup and tool reference
  • flowstudio-power-automate-debug
    — Debug failing flows after deployment
  • flowstudio-power-automate-mcp
    — 核心连接设置和工具参考
  • flowstudio-power-automate-debug
    — 部署后调试失败的流