Flow Studio Blog

Auto-Document Power Automate Flows with Claude or GitHub Copilot

Written by Catherine Han | Apr 27, 2026 10:19:56 AM

How do I document my Power Automate flows? It comes up in every Power Platform community forum I read. It is a real pain for the people responsible for flows. Very few people enjoy reading through old flows and turning them into documentation.

Nowadays with GPT this has been easier - many people throw the definition into GPT and ask it to summarize the flow. But it is still manual - you need to do it flow by flow. 

I have three autonomous approaches with MCP that resolve the problem in bulk. Even if you have hundreds of flows, these approaches won't take you more than a half day to document the first draft (assuming human review final outcome would still take time). With the MCP free quota,  <70 flows is likely to be completely free.

This article is the first of the trilogy - this is the developer path: an AI coding agent in your IDE writes the docs, you review and ship.

I didn't open Power Automate designer once.

What it took:

  • One prompt (a paragraph)
  • Two tools wired in (Flow Studio MCP for the read side, a Service Principal with SharePoint scope for the write side)
  • One spec: the 6 inventory columns and 7 page sections I wanted, written into the prompt itself. No pre-built template page needed; the agent assembled the pages from my prompt.

For the first small-batch trial, the agent picked three flows for me to sanity-check first, drafted a page per flow, registered each in the inventory, then batched the remaining 43.

What I set up

1. A Service Principal with SharePoint writing access to the target site. I used an existing app registration in my tenant. Fresh setup is still small, but it is not just one checkbox. You create or reuse an app registration, grant it the Sites.Selected application permission, then call Microsoft Graph to grant that app write access to one specific SharePoint site. The agent can tell you the exact Graph request to run. After that, it uses an app-only token and can only write to the selected site.

Tip: If you don't know how to set this up, ask your agent to do it for you with the Azure CLI. I walked through that pattern in Stop Learning Power Automate (Path 2): you run az login once as yourself, then the agent creates the app registration, scopes the permissions, and writes the secret to its own environment.

2. Flow Studio MCP wired into the agent. Sign in to the Flow Studio MCP dashboard and copy an API key from the API Keys section, then pick the install path for your agent:

Agent Install
VS Code Copilot Marketplace → Ctrl+Shift+X → search "Flow Studio MCP" → Install. Paste key when prompted; stored in OS keychain.
Claude Code One CLI: claude mcp add --transport http flowstudio https://mcp.flowstudio.app/mcp --header 'x-api-key: <your-api-key>'

Tip: Need a step-by-step? The Flow Studio MCP setup guide walks through both the VS Code extension install and the Claude Code plugin install in detail.

3. The target SharePoint site, empty. I told the agent the URL and let it create the inventory list itself.

What the agent did

The prompt was deliberately short. I wanted to see if the section list plus the tools could carry the rest:

▸ Prompt to the agent

Document every Power Automate flow in the Flow Studio Demo environment. On the MCP Demo site, create a SharePoint list called FlowDocsInventory with these columns: Title (built-in), TriggerType, FlowURL, PageURL, RelevantTools, Summary.

For each flow, create a SharePoint page with these 7 sections in order: (1) What is this flow for, (2) How it is triggered, (3) Other inputs, (4) The process in plain language, (5) Relevant tools and systems, (6) A flow chart (mermaid → SVG), (7) Appendix of action inputs and parameters. Add a row to FlowDocsInventory for each page. Group similar flows so I can sanity-check three before you batch the rest.

Three Flow Studio MCP tools plus Microsoft Graph. Pipeline:

Read
list_live_flows
46 flows
Read
get_live_flow
trigger, actions, connections, expressions
 Write 
SharePoint pages + rows
 1 page + 1 inventory row per flow 
Write
Microsoft Graph
 create FlowDocsInventory list 
Human
I sanity-check 3

Blue = MCP read calls · Yellow = SharePoint writes via Graph · Green = my one human checkpoint

The screenshots below are the actual artifacts on MCPDemo, same data, easier to read at blog width.


FlowDocsInventory rows the agent wrote live SharePoint list.



Here is one of the three per-flow doc pages the agent produced. The other two pages, SQL GDR Monitor and Weekly Pending Approvals, use the same template; live pages for the SQL GDR Monitor flow doc and the Weekly Pending Approvals flow doc.



One per-flow doc page the agent produced. Same 7-section template no matter how complex the underlying flow. Live page: flowdocs-e1fd17ee-mcpdemo-upload-approval.aspx.


The template, and why it's two pieces not one

The split matters. The inventory list is the index you Ctrl-F when somebody asks "do we have a flow that does X?". The per-flow page is the drill-down you send to whoever has to maintain it next. Conflate them and you get one giant doc nobody reads.

Inventory list · the index · 1 row per flow Per-flow page · the drill-down · 1 page per flow

6 fields

  1. Title (built-in, flow display name)
  2. TriggerType
  3. FlowURL → make.powerautomate.com
  4. PageURL → SharePoint page
  5. RelevantTools (comma-delimited tags)
  6. Summary (2-3 sentences)

7 sections

  1. What is this flow for
  2. How it is triggered
  3. Other inputs
  4. The process (plain language)
  5. Relevant tools and systems
  6. Flow chart (mermaid → SVG)
  7. Appendix: action inputs/parameters

If you take one thing from this post

Take the template, not the agent. The 6-field inventory plus the 7-section page work whether you use Flow Studio MCP, a different MCP server, or write the docs by hand. The agent is an accelerator. The template is the asset.


Why give the agent the keys to SharePoint

This path is not for everyone. Here is the trade.

What it costs you What you get back
  • A service principal in Azure
  • An az CLI session
  • An IDE that can host an MCP agent
  • Dev-tools comfort, which not every M365 admin has
  • One-line security answer: one SharePoint site, read-write, rotatable, deletable
  • Rotate the secret, agent loses access
  • Delete the app registration, gone for good
  • Sites.Selected on one site, much smaller blast radius than handing your personal account to a flow that runs as you


If your environment can't grant a service principal at this scope

If your tenant locks down app registrations, or you can't get a per-site Sites.Selected grant approved without weeks of admin sign-off, there's a second path that swaps the SharePoint app for a Power Automate cloud flow. The agent never touches SharePoint directly. It calls one flow, the flow does the writes.

Path How it writes Best for Trade-off
Service Principal Agent writes through Graph Faster runtime Needs app registration and Sites.Selected grant
Dispatcher flow Agent calls a flow Locked-down tenants Slower, each write is a flow run

Security note: treat the dispatcher flow URL like a write credential. Use a dedicated environment, restrict who can edit or call it, validate an auth header or shared secret in the trigger body, and rotate the URL if exposed. 

The meta part:
I had the agent build the dispatcher flow itself, using Flow Studio MCP's flow-build skill. Same agent, same MCP server, just used in the other direction. The agent wrote a flow to act as its own SharePoint write surface.

The working flow in my tenant exposes one tool to the agent with an action enum and eight operations covering the full SharePoint Pages lifecycle: List, Read, Create, Modify, Checkout, Publish, Discard, Recycle. The agent calls it like any other tool: "Create a page with this title and these sections" → flow run → published page.

Each action wraps a SharePoint REST call. Here's what the flow gives the agent:

Action Purpose
List Find existing pages
Read Fetch a page
Create Create a new page
Checkout Lock for edit
Modify Patch title or canvas
Publish Publish page
Discard Roll back edit
Recycle Soft-delete page

 

What the dispatcher flow actually looks like in the Power Automate designer:

One HTTP trigger, one Switch on Action, eight cases. One case per SharePoint REST operation.

Create and Modify have extra Compose actions. Build_Canvas wraps your HTML in the CanvasContent1 envelope; Build_Body adds Title, FileName, and PageLayoutType before the SharePoint POST or PATCH.

Typical agent chain (happy path): CreateCheckoutModifyPublish.

Other actions: Discard rolls back an in-flight edit. List and Read are the pre-flight reads. Recycle is soft-delete, separate from the edit cycle.

The 6-column inventory plus the 7-section page spec from earlier still applies, unchanged. Only the write surface swaps. The agent learns one new tool (the flow) instead of one new credential (the app registration).

Try it in your tenant

  1. Pick a small environment. 5-20 flows is a reasonable batch once you trust the output. Mine had 46 and the agent picked 3 to start; same logic at any size.
  2. Set up the write surface. Pick one: an Azure app registration with Sites.Selected on the target site (Path 1, fast at runtime, needs admin grant), or a Power Automate dispatcher flow with an HTTP trigger (Path 2, slower at runtime, no Azure work). The agent can build either one for you. Sign in to az first for Path 1, or hand the agent the Flow Studio MCP build skill for Path 2.
  3. Install Flow Studio MCP. Marketplace extension on VS Code Copilot, one claude mcp add command on Claude Code. Starter plan is free; current limits on the dashboard.
  4. Hand over the section spec and the prompt. Don't pre-build a template page. List the columns and sections you want; the agent assembles each page from the spec. Iterate on the first one or two flows until the doc reads the way you want, then let the agent batch the rest.

About Flow Studio MCP: Flow Studio MCP is a Model Context Protocol server that gives AI agents action-level visibility into Power Automate. It's Available on GitHub via the awesome-copilot list. Works with GitHub Copilot, Claude, and any MCP-compatible agent.

Related reading:

Appendix - Dispatcher actions 

Action Purpose Method URI Body
List Find pages that already exist on the site (pre-flight before Create or Modify) GET _api/sitepages/pages?$select=Id,Title,FileName,PageLayoutType,Modified&$orderby=Modified desc&$top=100 (none)
Read Fetch one page's full record (metadata + canvas content) GET _api/sitepages/pages({pageId}) (none)
Create Make a new page from your HTML POST _api/sitepages/pages
{
  "Title": "How I document Power Automate flows",
  "FileName": "my-page.aspx",
  "PageLayoutType": "Article",
  "CanvasContent1": [
    {
      "controlType": 4,
      "position": {
        "layoutIndex": 1, "zoneIndex": 1,
        "sectionIndex": 1, "sectionFactor": 12,
        "controlIndex": 1
      },
      "addedFromPersistedData": true,
      "editorType": "CKEditor",
      "id": "<guid>",
      "innerHTML": "<p>Your page HTML</p>"
    },
    {
      "controlType": 0,
      "pageSettingsSlice": {
        "isDefaultDescription": true,
        "isDefaultThumbnail": true
      }
    }
  ]
}
Checkout Lock the page so edits commit cleanly POST _api/sitepages/pages({pageId})/checkoutPage (none)
Modify Patch title and/or canvas. Smart-merge: only fields you pass get updated PATCH
extra header: IF-MATCH: *
_api/sitepages/pages({pageId})
{
  "Title": "Updated title",
  "CanvasContent1": [
    {
      "controlType": 4,
      "position": { "...": "..." },
      "editorType": "CKEditor",
      "id": "<guid>",
      "innerHTML": "<p>Updated HTML</p>"
    },
    {
      "controlType": 0,
      "pageSettingsSlice": { "...": "..." }
    }
  ]
}
Both fields optional. Pass only what you want to change.
Publish Promote the checked-in version to what readers see POST _api/sitepages/pages({pageId})/publish (none)
Discard Abort an in-flight edit, revert to last published POST _api/sitepages/pages({pageId})/discardPage (none)
Recycle Soft-delete the page (recoverable from recycle bin) POST _api/web/getfilebyserverrelativeurl('/sites/<site>/SitePages/{pageName}.aspx')/recycle (none)

 

Default headers: every endpoint sends Accept: application/json;odata=nometadata.

Writes: POST and PATCH also send Content-Type: application/json;odata=nometadata.

CanvasContent1 on the wire: shown above as a JSON array for readability. SharePoint actually expects it as a JSON-encoded string; the SharePoint connector in Power Automate handles that stringification for you.

 

Catherine Han, Flow Studio