mcpField
F
flowstudio-power-automate-build

flowstudio-power-automate-build

github.com/github生产力40.5k1.9k 次安装今天更新
代码仓库

关于 flowstudio-power-automate-build

这是一项通过 FlowStudio MCP 构建、部署、验证和测试 Power Automate 云端流的流程指南,面向执行工作流自动化的 Agent,涵盖工具发现、连接器配置及安全测试。

主要功能

  1. 01发现当前构建工具的架构
  2. 02检查是否已有流程
  3. 03解析连接器连接
  4. 04构建并部署流程定义
  5. 05验证和测试部署结果

适用场景

  1. 01创建新的云端流程
  2. 02修改现有流程
  3. 03配置连接器引用
  4. 04使用前验证部署

MCP 相关

通过 FlowStudio MCP 服务发现工具、检查环境和连接,并部署、验证或测试流程。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/github/awesome-copilot --skill flowstudio-power-automate-build

安装后在 Claude Code 中输入/flowstudio-power-automate-build确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
action-patterns-connectors.md
action-patterns-core.md
action-patterns-data.md
build-patterns.md
flow-schema.md
trigger-types.md

详细介绍

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

通过 FlowStudio MCP 服务以编程方式构建和部署 Power Automate 云端流的分步指南。

前提条件:必须能够使用有效的 JWT 访问 FlowStudio MCP 服务。 有关连接设置,请参阅 flowstudio-power-automate-mcp 技能。 在 https://mcp.flowstudio.app 订阅

工作流:

  1. 加载当前构建工具。
  2. 检查是否存在现有流。
  3. 解析连接引用。
  4. 构建定义。
  5. 部署。
  6. 验证。
  7. 测试。

事实来源

始终先调用 list_skills / tool_search,以确认可用的工具 名称和参数 schema。工具名称和参数可能会在 服务版本之间发生变化。 本技能涵盖响应结构、行为说明和构建模式—— 这些是工具 schema 无法告诉你的内容。如果本文档与 tool_search 或真实 API 响应不一致,以 API 为准。


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

0. 加载当前构建工具

对于全新的流,加载服务的 create-flow 捆绑包。对于编辑 现有流,加载 build-flow。这样可以在构建 JSON 之前,让 Agent 与 MCP 服务的当前 schema 保持一致。

schemas = mcp("tool_search", query="skill:create-flow")
# Includes list_live_environments, list_live_connections,
# describe_live_connector, get_live_dynamic_options, update_live_flow.

如果需要捆绑包之外的工具,请显式加载:

mcp("tool_search", query="select:get_live_dynamic_properties")

1. 安全检查:流是否已经存在?

始终先查看再构建,以避免重复:

results = mcp("list_live_flows",
    environmentName=ENV,
    mode="owner",
    search="My New Flow",
    top=20)

# list_live_flows returns { "flows": [...], "mode": "...", ... }
matches = [f for f in results["flows"]
           if "My New Flow".lower() in f["displayName"].lower()]

if len(matches) > 0:
    # Flow exists — modify rather than create
    FLOW_ID = matches[0]["id"]   # plain UUID from list_live_flows
    print(f"Existing flow: {FLOW_ID}")
    defn = mcp("get_live_flow", environmentName=ENV, flowName=FLOW_ID)
else:
    print("Flow not found — building from scratch")
    FLOW_ID = None

对于非常大的环境,list_live_flows 可能会返回一个 continuation URL。 将其作为 continuationUrl 传回,并使用相同的 mode 来获取下一 批数据。仅当用户需要所有环境流,且 MCP 身份具有管理员权限时,才使用 mode="admin"。


2. 获取连接引用

每个连接器操作都需要一个 connectionName,它指向流的 connectionReferences 映射中的某个键。该键链接到环境中一个 经过身份验证的连接。

强制要求:你必须先调用 list_live_connections——不要向 用户询问连接名称或 GUID。API 会返回你需要的精确值。 只有当 API 确认缺少所需连接时,才提示用户。

2a — 查找活动连接
conns = mcp("list_live_connections", environmentName=ENV)
active = [c for c in conns["connections"]
          if c["statuses"][0]["status"] == "Connected"]
conn_map = {c["connectorName"]: c["id"] for c in active}

对于已知连接器,传入 search 以减少输出,并获得可直接粘贴的 connectionReferenceTemplate 和 hostTemplate 值:

sp_conns = mcp("list_live_connections",
    environmentName=ENV,
    search="shared_sharepointonline")
2b — 确定流需要哪些连接器

常见连接器 API 名称:SharePoint shared_sharepointonline、Outlook shared_office365、Teams shared_teams、Approvals shared_approvals、 OneDrive shared_onedriveforbusiness、Excel shared_excelonlinebusiness、 Dataverse shared_commondataserviceforapps、Forms shared_microsoftforms。

不需要连接器的流,例如仅包含 Recurrence + Compose + HTTP 的流,可以 省略 connectionReferences。

2c — 如果连接缺失,请引导用户
connectors_needed = ["shared_sharepointonline", "shared_office365"]  # adjust per flow
missing = [c for c in connectors_needed if c not in conn_map]
if missing:
    # STOP: connections require browser OAuth consent.
    # Ask the user to create the missing connector connections in the
    # selected environment, then re-run list_live_connections.
    raise Exception(f"Missing active connections: {missing}")
2d — 构建 connectionReferences 块
connection_references = {}
host_templates = {}
for connector in connectors_needed:
    c = next(c for c in active if c["connectorName"] == connector)
    connection_references[connector] = c.get("connectionReferenceTemplate") or {
        "connectionName": c["id"],   # the connection id from list_live_connections
        "source": "Invoker",
        "id": f"/providers/Microsoft.PowerApps/apis/{connector}"
    }
    host_templates[connector] = c.get("hostTemplate") or {
        "connectionName": connector
    }

在第 3 步的操作 JSON 中,inputs.host.connectionName 必须是映射键,例如 shared_teams,而不是 GUID。GUID 只属于 connectionReferences[connector].connectionName 值。如果现有流使用了 相同的连接器,你也可以从 get_live_flow 复制其 properties.connectionReferences。


3. 构建流定义

构建定义对象。完整 schema 请参阅 flow-schema.md, 并参阅以下操作模式参考以获取可复制粘贴的模板:

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
}

完整、可直接使用的流定义请参阅 build-patterns.md, 其中涵盖 Recurrence+SharePoint+Teams、HTTP 触发器等。

在猜测 JSON 之前,先发现连接器操作

对于由连接器支持的触发器和操作,优先使用实时连接器描述器,而不是 手写结构。它可以返回作者提供的提示、规范示例、变体 键、输入/输出以及动态元数据指针。

# Search across connectors when you know the user's intent but not the API.
matches = mcp("describe_live_connector",
    environmentName=ENV,
    search="send email",
    top=5)

# Describe a specific operation before copying an exampleDefinition.
op = mcp("describe_live_connector",
    environmentName=ENV,
    connectorName="shared_office365",
    operationId="SendEmailV2")
print(op.get("hint"))

当一个操作有多个作者提供的变体时,请求流程 所需的那个变体:

teams_chat = mcp("describe_live_connector",
    environmentName=ENV,
    connectorName="shared_teams",
    operationId="PostMessageToConversation",
    variant="flowbot_chat")

当操作说明指出某个参数具有动态选项或动态 属性时,调用所指示的下一工具:

sp_op = mcp("describe_live_connector",
    environmentName=ENV,
    connectorName="shared_sharepointonline",
    operationId="GetItems")

sites = mcp("get_live_dynamic_options",
    environmentName=ENV,
    connectorName="shared_sharepointonline",
    connectionName=conn_map["shared_sharepointonline"],
    operationId="GetItems",
    parameterName="dataset",
    dynamicMetadata=sp_op["dynamicParameters"]["dataset"])

fields = mcp("get_live_dynamic_properties",
    environmentName=ENV,
    connectorName="shared_sharepointonline",
    connectionName=conn_map["shared_sharepointonline"],
    operationId="GetItems",
    parameterName="item",
    parameters={"dataset": "<site-url>", "table": "<list-id>"},
    dynamicMetadata=sp_op["dynamicProperties"]["item"])

对 SharePoint 网站/列表和 Teams 团队/频道等下拉 ID 使用动态选项。对 SharePoint 列表项列等 架构/字段结构使用动态属性。


4. 部署(创建或更新)

update_live_flow 在单个工具中同时处理创建和更新。

创建新流程(没有现有流程)

省略 flowName —— 服务会生成一个新的 GUID 并通过 PUT 创建:

definition["description"] = "Weekly SharePoint → Teams notification flow, built by agent"

result = mcp("update_live_flow",
    environmentName=ENV,
    # flowName omitted → creates a new flow
    definition=definition,
    connectionReferences=connection_references,
    displayName="Overdue Invoice Notifications"
)

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 以进行 PATCH:

definition["description"] = (
    "Updated by agent on " + __import__('datetime').datetime.utcnow().isoformat()
)

result = mcp("update_live_flow",
    environmentName=ENV,
    flowName=FLOW_ID,
    definition=definition,
    connectionReferences=connection_references,
    displayName="My Updated Flow"
)

if result.get("error") is not None:
    print("Update failed:", result["error"])
else:
    print("Update succeeded:", result)

⚠️ update_live_flow 始终返回一个 error 键。 null(Python 中的 None)表示成功 —— 不要将存在该键视为失败。

⚠️ 流程描述位于 definition["description"]。当前服务 会附加 #flowstudio-mcp 以进行使用跟踪。除非 tool_search 在活动架构中显示存在顶层 description 参数,否则不要传入它。

常见部署错误
错误消息(包含)原因修复
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

5. 验证部署

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

# Confirm state
print("State:", check["properties"]["state"])  # Should be "Started"
# If state is "Stopped", use set_live_flow_state — NOT update_live_flow
# mcp("set_live_flow_state", environmentName=ENV, flowName=FLOW_ID, state="Started")

# Confirm the action we added is there
acts = check["properties"]["definition"]["actions"]
print("Actions:", list(acts.keys()))

6. 测试流程

强制要求:在触发任何测试运行之前,先向用户请求确认。 运行流程会产生真实的副作用 —— 它可能会发送电子邮件、发布 Teams 消息、 写入 SharePoint、启动审批或调用外部 API。说明该 流程将做什么,并在调用 trigger_live_flow 或 resubmit_live_flow_run 之前等待明确批准。

已更新的流程(有先前运行)—— 任何触发器类型

优先使用 resubmit_live_flow_run。 它适用于每一种触发器类型 —— Recurrence、SharePoint、连接器 webhook、Button 和 HTTP。它会重放 原始触发器负载。不要要求用户手动触发 流程或等待下一次计划运行。

runs = mcp("get_live_flow_runs", environmentName=ENV, flowName=FLOW_ID, top=1)
if runs:
    # Works for Recurrence, SharePoint, connector triggers — not just HTTP
    result = mcp("resubmit_live_flow_run",
        environmentName=ENV, flowName=FLOW_ID, runName=runs[0]["name"])
    print(result)   # {"resubmitted": true, "triggerName": "..."}
HTTP、Button 和 PowerApps 流程 —— 自定义测试负载

仅当你需要发送与原始运行不同的负载时, 才使用 trigger_live_flow。对于验证修复,resubmit_live_flow_run 更好,因为它使用导致失败的确切数据。

defn = mcp("get_live_flow", environmentName=ENV, flowName=FLOW_ID)
triggers = defn["properties"]["definition"]["triggers"]
manual = next(iter(triggers.values()))
print("Expected body:", manual.get("inputs", {}).get("schema"))

result = mcp("trigger_live_flow",
    environmentName=ENV, flowName=FLOW_ID,
    body={"name": "Test", "value": 1})
print(f"Status: {result['responseStatus']}, via: {result['invocation']}")
print(result.get("warning"))   # set when a required input was missing: the run still ran, with null
全新的非 HTTP 流程

全新的 Recurrence 流程无需变通方法:部署它,然后 立即使用 trigger_live_flow 且不带 body 运行它 —— 与门户中的 "Run flow" 按钮相同。body 会被拒绝;计划触发器不接受任何输入。

全新的连接器触发流程(SharePoint、webhook)没有先前 运行,并且没有真实的源事件就无法触发。使用临时的 HTTP 触发器部署,测试操作,然后切换到生产触发器:

production_trigger = definition["triggers"]
definition["triggers"] = {
    "manual": {"type": "Request", "kind": "Http", "inputs": {"schema": {}}}
}
result = mcp("update_live_flow", environmentName=ENV,
    flowName=FLOW_ID,       # omit if creating new
    definition=definition, connectionReferences=connection_references,
    displayName="Overdue Invoice Notifications")
FLOW_ID = FLOW_ID or result["flowName"]

mcp("trigger_live_flow", environmentName=ENV, flowName=FLOW_ID,
    body={"sample": "payload"})
runs = mcp("get_live_flow_runs", environmentName=ENV, flowName=FLOW_ID, top=1)
if runs[0]["status"] == "Failed":
    err = mcp("get_live_flow_run_error",
        environmentName=ENV, flowName=FLOW_ID, runName=runs[0]["name"])
    raise Exception(err["failedActions"][-1])

definition["triggers"] = production_trigger
mcp("update_live_flow", environmentName=ENV, flowName=FLOW_ID,
    definition=definition, connectionReferences=connection_references)

触发器只是入口点;通过 HTTP 测试仍然会执行 相同的操作。如果操作使用 triggerBody() 或 triggerOutputs(),请传入一个 形状与生产触发器负载一致的代表性 body。


常见陷阱

错误后果预防措施
部署时缺少 connectionReferences400 "Supply connectionReferences"始终先调用 list_live_connections
Foreach 上缺少 "operationOptions"并行执行,写入时产生竞态条件始终添加 "Sequential"
union(old_data, new_data)旧值覆盖新值(先到者优先)使用 union(new_data, old_data)
对可能为 null 的字符串调用 split()InvalidTemplate 崩溃用 coalesce(field, '') 包裹
检查 result["error"] 是否存在该字段始终存在;真正的错误是 != null使用 result.get("error") is not None
流已部署但状态为 "Stopped"流不会按计划运行调用 set_live_flow_state 并传入 state: "Started" —— 不要用 update_live_flow 更改状态
Teams "Chat with Flow bot" 收件人使用对象400 GraphUserDetailNotFound使用末尾带分号的纯字符串(见下文)
Copilot/Skills 流不在解决方案中Copilot Studio 可能无法将其识别为 Agent 工具部署后调用 add_live_flow_to_solution,传入目标 solutionId
使用 Button/Skills 触发器进行 MCP 测试即使缺少必填输入(null)也会运行在 trigger_live_flow 的 body 中传入输入;若出现 warning,取消并用完整 body 重试
连接器操作缺少 metadata.operationMetadataId设计器/仅运行 UI 可能表现不一致保留现有 ID;为新连接器操作添加稳定的 GUID
占位符 Excel scriptId保存时动态验证失败部署前解析真实的 Office Script ID
SharePoint PatchItem 遗漏必填字段即使该字段未更改,保存也可能失败回传未更改的必填字段,例如 item/Title
Copilot Studio 连接器调用草稿 Agent连接器调用可能失败或触发陈旧行为在测试/重新提交流之前先发布 Agent
Teams PostMessageToConversation —— 收件人格式

body/recipient 参数的格式取决于 location 的值:

Locationbody/recipient 格式示例
Chat with Flow bot带末尾分号的纯电子邮件字符串"[email protected];"
Channel包含 groupId 和 channelId 的对象{"groupId": "...", "channelId": "..."}

常见错误:为 "Chat with Flow bot" 传入 {"to": "[email protected]"} 会返回 400 GraphUserDetailNotFound 错误。API 期望的是纯字符串。


参考文件

相关技能

  • flowstudio-power-automate-mcp —— 核心连接设置与工具参考
  • flowstudio-power-automate-debug —— 部署后调试失败的流

评论

支持 Markdown