Build & Deploy Power Automate Flows with FlowStudio MCP
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 power-automate-mcp skill for connection setup.
Subscribe at 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.
Python Helper
CODEBLOCK0
Step 1 — Safety Check: Does the Flow Already Exist?
Always look before you build to avoid duplicates:
CODEBLOCK1
Step 2 — Obtain Connection References
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.
2a — Always call list_live_connections first
CODEBLOCK2
2b — Determine which connectors the flow needs
Based on the flow you are building, identify which connectors are required.
Common connector API names:
| Connector | API name |
|---|
| SharePoint | INLINECODE8 |
| 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.
2c — If connections are missing, guide the user
CODEBLOCK3
2d — Build the connectionReferences block
Only execute this after 2c confirms no missing connectors:
CODEBLOCK4
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:
CODEBLOCK5
See the power-automate-mcp skill's connection-references.md reference
for the full connection reference structure.
Step 3 — Build the Flow Definition
Construct the definition object. See flow-schema.md
for the full schema and these action pattern references for copy-paste templates:
CODEBLOCK6
See build-patterns.md for complete, ready-to-use
flow definitions covering Recurrence+SharePoint+Teams, HTTP triggers, and more.
Step 4 — Deploy (Create or Update)
INLINECODE24 handles both creation and updates in a single tool.
Create a new flow (no existing flow)
Omit flowName — the server generates a new GUID and creates via PUT:
CODEBLOCK7
Update an existing flow
Provide flowName to PATCH:
CODEBLOCK8
⚠️ 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.
Common deployment errors
| Error message (contains) | Cause | Fix |
|---|
| INLINECODE32 | 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 |
| INLINECODE38 / 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 |
|
InvalidTemplate /
InvalidDefinition | Syntax error in the definition JSON | Check
runAfter chains, expression syntax, and action type spelling |
|
ConnectionNotConfigured | A connector action exists but the connection GUID is invalid or expired | Re-check
list_live_connections for a fresh GUID |
Step 5 — Verify the Deployment
CODEBLOCK9
Step 6 — Test the Flow
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.
Updated flows (have prior runs)
The fastest path — resubmit the most recent run:
CODEBLOCK10
Flows already using an HTTP trigger
Fire directly with a test payload:
CODEBLOCK11
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.
7a — Save the real trigger, deploy with a temporary HTTP trigger
CODEBLOCK12
7b — Fire the flow and check the result
CODEBLOCK13
7c — Swap to the production trigger
Once the test run succeeds, replace the temporary HTTP trigger with the real one:
CODEBLOCK14
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.
Gotchas
| Mistake | Consequence | Prevention |
|---|
Missing connectionReferences in deploy | 400 "Supply connectionReferences" | Always call list_live_connections first |
| INLINECODE53 missing on Foreach |
Parallel execution, race conditions on writes | Always 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 schedule | Check connection auth; re-enable |
| Teams "Chat with Flow bot" recipient as object | 400
GraphUserDetailNotFound | Use plain string with trailing semicolon (see below) |
Teams PostMessageToConversation — Recipient Formats
The body/recipient parameter format depends on the location value:
| Location | INLINECODE67 format | Example |
|---|
| Chat with Flow bot | Plain email string with trailing semicolon | INLINECODE68 |
| Channel |
Object 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.
Reference Files
Related Skills
- -
power-automate-mcp — Core connection setup and tool reference - INLINECODE75 — Debug failing flows after deployment
使用FlowStudio MCP构建和部署Power Automate流
通过FlowStudio MCP服务器以编程方式构建和部署Power Automate云端流的逐步指南。
前提条件:必须能够访问有效的FlowStudio MCP服务器,并持有有效的JWT令牌。
连接设置请参见power-automate-mcp技能。
订阅地址:https://mcp.flowstudio.app
事实来源
始终先调用tools/list 以确认可用的工具名称及其参数模式。工具名称和参数可能因服务器版本而异。
本技能涵盖响应结构、行为说明和构建模式——这些是tools/list无法告知的内容。如果本文档与tools/list或实际API响应存在差异,以API为准。
Python辅助函数
python
import json, urllib.request
MCP_URL = https://mcp.flowstudio.app/mcp
MCPTOKEN = 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(fMCP HTTP {e.code}: {body[:200]}) from e
raw = json.loads(resp.read())
if error in raw:
raise RuntimeError(fMCP error: {json.dumps(raw[error])})
return json.loads(raw[result][content][0][text])
ENV = # 例如 Default-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
步骤1 — 安全检查:流是否已存在?
在构建之前始终先检查,避免重复创建:
python
results = mcp(liststoreflows,
environmentName=ENV, searchTerm=My New Flow)
liststoreflows 返回直接数组(无包装对象)
if len(results) > 0:
# 流已存在 — 修改而非创建
# id格式为 envId.flowId — 拆分获取流UUID
FLOW_ID = results[0][id].split(., 1)[1]
print(f现有流: {FLOW_ID})
defn = mcp(get
liveflow, environmentName=ENV, flowName=FLOW_ID)
else:
print(未找到流 — 从头构建)
FLOW_ID = None
步骤2 — 获取连接引用
每个连接器操作都需要一个connectionName,指向流的connectionReferences映射中的键。该键链接到环境中已认证的连接。
必须执行:您必须先调用listliveconnections — 不要询问用户连接名称或GUID。API会返回您需要的精确值。
仅当API确认所需的连接缺失时,才提示用户。
2a — 始终先调用listliveconnections
python
conns = mcp(listliveconnections, environmentName=ENV)
仅筛选已连接(已认证)的连接
active = [c for c in conns[connections]
if c[statuses][0][status] == Connected]
构建查找表:connectorName → connectionName (id)
conn_map = {}
for c in active:
conn_map[c[connectorName]] = c[id]
print(f找到 {len(active)} 个活动连接)
print(可用连接器:, list(conn_map.keys()))
2b — 确定流需要哪些连接器
根据您正在构建的流,确定需要哪些连接器。常见连接器API名称:
| 连接器 | API名称 |
|---|
| SharePoint | sharedsharepointonline |
| Outlook / Office 365 |
sharedoffice365 |
| 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 — 如果连接缺失,引导用户
python
connectorsneeded = [sharedsharepointonline, shared_office365] # 根据流调整
missing = [c for c in connectorsneeded if c not in connmap]
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 — 构建connectionReferences块
仅在2c确认没有缺失连接后执行:
python
connection_references = {}
for connector in connectors_needed:
connection_references[connector] = {
connectionName: connmap[connector], # 来自listlive_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
refflow = mcp(getlive_flow, environmentName=ENV, flowName=)
connectionreferences = refflow[properties][connectionReferences]
有关完整的连接引用结构,请参见power-automate-mcp技能的connection-references.md参考文件。
步骤3 — 构建流定义
构建定义对象。有关完整模式,请参见flow-schema.md,以下是可复制粘贴模板的操作模式参考:
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
}
有关涵盖Recurrence+SharePoint+Teams、HTTP触发器等的完整即用型流定义,请参见build-patterns.md。
步骤4 — 部署(创建或更新)
updateliveflow在单个工具中处理创建和更新。
创建新流(无现有流)
省略flowName — 服务器生成新的GUID并通过PUT创建:
python
result = mcp(updateliveflow,
environmentName=ENV,
# flowName