TL;DR: I open-sourced an IT service desk built almost entirely by AI agents — 30+ production Power Automate flows, a Copilot Studio triage agent, six scoped executors, and an SPFx portal, all on the Microsoft 365 a tenant already pays for. It won the Cowork Collective track of Microsoft's Agent Academy hackathon. This is the teardown: the architecture, the build phase by phase, the security model, and the parts that aren't production-hardened. The repo is public — your own agent can read it and stand the whole thing up. github.com/ninihen1/copilot-studio-itsm-agent
One thing up front, because it changes how you should read the rest: this is a working proof of concept, not a production-hardened product. The core ticket → triage → approve → execute → audit pipeline runs on a live Microsoft 365 tenant, end to end. Off the happy path there are rough edges, and a few paths are designed and specced rather than fully wired — the repo is explicit about which. Treat it as a reference build to learn from, not a turnkey download. I'll point out the seams as we go.
Most ITSM platforms — ServiceNow, Jira Service Management, Zendesk — charge per seat, per month, and for a small or medium business that runs into the thousands a year. For what is mostly password resets, group adds, and licence requests, that's hard to justify. The bet here: do the same job on tools an M365 tenant already has — SharePoint, Power Automate, and Copilot Studio — and automate the routine work end to end. No separate ticketing subscription, no per-agent SaaS fee, one identity model, one security boundary.
The second bet, and the more interesting one: don't build it by hand. The whole system is designed to be co-worked with AI agents. The person who ran this build had never deployed an SPFx package by hand and didn't need to learn — the agent did it. The labour shifts from "build and operate a ticketing platform" to "supervise an agent that does."
It's an event-driven pipeline. There is no chatbot to talk to — the agent isn't a front door, it's a triage brain a flow calls in the background on the submitted ticket. Six stages:
Here's the live pipeline doing the scary part safely — the manager's approval card, then the change landing in Entra:
The portal isn't a SharePoint list form. It's a full-screen SPFx (SharePoint Framework) web part — a React single-page app (SPFx 1.22 / Heft / TypeScript) hosted on a SharePoint page, backed by a dozen-plus SharePoint lists. It follows the open-source vibe-sharepoint-template pattern, which treats SharePoint Online as a host for internal apps and hides the SharePoint chrome for an app-like feel. The instruction to the agent was essentially "point at this template and follow it."
One web part hosts the whole experience: a Home dashboard, a Service Catalog with item dialogs, a Knowledge Base, My Tickets and ticket detail, Approvals, an IT Service Desk hand-off queue, and an Admin view. A typed service layer (TicketService, CatalogService, ApprovalService…) reads and writes the SharePoint lists directly — read-only except explicit user actions, and no privileged Graph calls ever run in the browser. It ships as an .sppkg to the site-collection app catalog on /sites/ITSM through a certificate-authenticated GitHub Actions pipeline.
The notable part: this SPFx portal was built and shipped by AI agents, not a front-end team. An agent wrote the React/TypeScript, stood up the deployment pipeline, and from then on patched the portal's own source and shipped each change through CI/CD. A real production SharePoint app, built and maintained by agents under one person's supervision.
This is the runbook view — how an agent (with you shepherding) actually stands it up. The constant here is Flow Studio MCP, not the agent: the flows are built, run, and debugged through the MCP server, and it works with Claude, Codex, GitHub Copilot, or Copilot Cowork — use whichever agent you already work in. This build happened to use two: an IDE agent (Claude Code) and Copilot Cowork. The only real split is one capability boundary — authoring the Copilot Studio triage agent needs an IDE agent with the Copilot Studio extension; every other phase, either agent handles. The human directs and reviews.
SP-IT-Provisioning, with Sites.FullControl.All (application), a self-signed certificate uploaded to the app and stored locally for PnP, admin-consented. This is the only broad grant in the build, and it's used once, to create lists — not at runtime. No standing admin account.infra/sharepoint/ to create the 19 solution lists — Tickets, Service Catalog, Approval Policies, Provisioning Jobs, License Costs, Catalog Demand, and the rest — and seed the taxonomy. (IDE agent ran them here; Cowork can stand up the same schema a different way — a helper flow that creates each list through the SharePoint connector. Same schema, different mechanism.)agents/triage/. Wire the orchestrator flow that fires on a new ticket and calls the agent.flows/ — orchestrator, approval, dispatcher, and the six executors. Every flow was agent-written; none of the flow JSON was hand-authored. ~20 production flows ship in the repo (40-plus counting helpers and earlier iterations retired along the way). When a run fails, the agent reads the action-level outputs, confirms the bug, and patches the definition itself.src/ and stands up the deployment plumbing — a deployment Entra app, a certificate, the GitHub environment secrets, the site-collection app catalog, and the spfx-build-deploy.yml workflow. After that, an agent patches the portal's own code and pushes; the existing pipeline builds and deploys it.The full version — every identity, the exact order, and the gotchas (Copilot Studio's flow binding needing a named solution is the one that bites everyone) — is in the repo's IMPLEMENTATION-PLAYBOOK.md and DEPLOYMENT.md. Your agent reads those; you don't have to.
The "when a run fails, read the action outputs and fix it" line above is the whole reason an agent can build 30+ flows without a human in the JSON. The Power Automate Graph API only returns a top-level run status — "Failed." Flow Studio MCP gives the agent the action-level inputs and outputs of a live run, so it can see which action failed and why — a wrong field name, a type mismatch, an expired connection — then patch the definition and resubmit.
That loop — get the live flow, confirm the exact bug from the run detail, deploy the fix — is what turns "agent generates a flow that probably works" into "agent ships a flow that does."
Because the agent acts only through flows, it can reach anything Power Automate can — including systems outside the Power Platform. To patch the SPFx portal, an agent built a GitHub API proxy flow: one flow that commits files, opens branches and pull requests, merges, and runs and monitors GitHub Actions. It used that flow to ship the portal's own source through CI/CD without ever leaving Power Automate. That's the execution-layer idea in miniature — if a flow can reach it, the agent can act on it.
An agent also handled the project management around the build: running on a schedule against its own task board and generating a documentation page for each flow it shipped. Useful for grinding through a backlog with light oversight, though not hands-off — left alone for a week it drifted and needed a course-correct.
The whole design assumes an AI is in the loop, so the guardrails are deliberate. Enforced in the pilot today:
Config row the dispatcher checks on every job. Flip it and all execution freezes instantly: every job returns 503 before any tenant change, while intake, triage, and approvals keep working.The six executors and their scopes:
| Executor | Service principal | Job-type prefix | Scope target |
|---|---|---|---|
| Identity | SP-IT-Identity |
identity.* |
Password Administrator for password/MFA; user lifecycle behind a higher approval tier. Never Global Admin. |
| Groups | SP-IT-Groups |
groups.* |
Constrained to an allow-list of managed groups. |
| Licensing | SP-IT-Licensing |
licensing.* |
Approved SKUs only; seat-count pre-check; revoke only the SKU requested. |
| Exchange | SP-IT-Exchange |
exchange.* |
Mailbox permission changes behind a cert-auth Azure Function with explicit Exchange RBAC. |
| SharePoint | SP-IT-SharePoint |
sharepoint.* |
Target Sites.Selected with explicit per-site grants. |
| Teams | SP-IT-Teams |
teams.* |
Narrow Graph channel/membership permissions plus a managed-team allow-list. |
The operating rule across all six: an executor rejects any job type outside its prefix, validates the target against an allow-list before any write, and logs target, job type, service principal, status, and correlation ID. The agent's output never passes a raw teamId or siteUrl straight to Graph.
The repo is explicit about the seams, and so am I. Designed and specced, but not yet wired in the pilot:
Sites.Selected, narrow Teams permissions, and certificate credentials with rotation.None of that undercuts the claim that matters here — an agent reliably built 30+ real flows through Flow Studio MCP — but it's the difference between "ran end to end on my tenant" and "ship it to yours unchanged." Don't do the latter.
It's open source and genuinely agent-buildable. Point your AI coworker at the repo and tell it to build the system in your tenant — it reads everything there and stands it up, building and debugging the flows through Flow Studio MCP (works with Copilot, Claude, and any MCP-compatible agent), and comes back to you for the tenant, admin consent, and approvals. You don't grind through the docs; your agent reads them.
Repo: github.com/ninihen1/copilot-studio-itsm-agent. And if you want to see the other end of the same idea — an agent that fixes Power Automate flows instead of building them — see I built a flow that fixes failed Power Automate flows.
This is an independent, open-source educational project, not affiliated with or endorsed by ServiceNow, Atlassian, Zendesk, or Microsoft. ServiceNow is a registered trademark of ServiceNow, Inc.; Jira and Jira Service Management are trademarks of Atlassian; Zendesk is a trademark of Zendesk, Inc. Microsoft, Microsoft 365, Copilot, Copilot Cowork, Copilot Studio, Power Automate, Power Platform, SharePoint, Teams, Exchange, Microsoft Entra, Microsoft Graph, and Azure are trademarks of the Microsoft group of companies. Names are used descriptively (nominative use). Flow Studio is not affiliated with or endorsed by these companies.