AgentLens: an Agent That Audits Your Agents
Tenants sprawl to hundreds of agents across four stores and nobody owns the whole picture. AgentLens sweeps them read-only, joins usage to real Azure spend, and never invents a number.
Project details
- TypeScript
- Model Context Protocol
- Microsoft 365 Copilot
- Bicep
- Azure Container Apps
- Azure Resource Graph
- Azure Cost Management
The problem nobody has when they sell the project
When a client goes from three agents to thirty, nobody knows any more who created them, what they read, what they cost, or which ones have been abandoned. It is the problem nobody has at the point of sale, and everybody has six months later.
The trigger was a single tenant where more than 4,000 agents showed up in the Power Platform admin console, around 3,500 of them Copilot Studio. Nobody on the client side knew what they were or who had created them. Two environments in total, one of them open to everyone. That observation is what created AgentLens.
Five tools, all read-only
AgentLens is a Microsoft 365 Copilot agent, so you ask it a question in Copilot chat. Behind it sits an MCP server that reads the tenant and answers with real numbers.
| Tool | Answers |
|---|---|
sweep_inventory | Every agent across the four stores, with owners, orphans and duplicate clusters |
dlp_posture | Which environments no DLP policy covers, and what that exposes |
value_and_cost | Which agents are actually used, what each consumes and costs, what Azure invoiced, and a verdict per agent |
consolidation_plan | Duplicate clusters, which agent to keep, and a plan you can send to owners |
agent_map | A self-contained SVG diagram of the whole estate |
The four stores it sweeps: Copilot Studio, M365 Agent Builder, Azure AI Foundry and Microsoft Fabric.
The one rule
AgentLens never fabricates data. An administrator makes retire-or-keep decisions from this output, and a security reviewer will ask what it can change. Both collapse if a single number is invented. So:
- Every figure comes from an API response in the same call, or is derived from one by arithmetic whose inputs and method ship alongside it.
- A source that cannot be read returns
not_connectedorpartial, naming the source, the reason and the fix. - Zero and unknown are different answers. A store that could not be read is never rendered as "0 agents"; the estate map draws it as a dashed not connected node.
- There is no sample or demo mode. With no credentials the agent says every source is not connected, which is the honest answer and the first thing worth testing.
Unreadable is not zero
The temptation in a governance tool is to render a missing source as an empty result, because an empty result looks like a clean estate. It is the single most dangerous thing such a tool can do: an administrator retires nothing, concludes there is nothing to retire, and the sprawl carries on unmeasured.
Separating zero from unknown costs you a tidier-looking dashboard and buys you a tool a security reviewer will actually sign off.
How it is built
- Two pieces, one repository. The agent package is the conversational surface; the MCP server is everything behind it.
- One read-only service principal reads Azure Resource Graph, Microsoft Graph, the Power Platform admin and governance APIs, Dataverse in aggregate, and Azure Cost Management.
- Infrastructure as code: Bicep and
azure.yaml, deployed to Azure Container Apps. No manual clicking in a portal. - Continuous integration: GitHub Actions with Vitest.
- Read-only tenant posture is a design constraint, not a setting: there is no write path to disable.
The commercial angle
Fleet governance sells as a recurring service, after the project. It turns a one-off engagement into a continuing relationship, and it is hard to dislodge once it is installed. That is the argument I make to integrators: the governance layer is the annuity that the build itself is not.
AgentLens was demoed at the Microsoft 365 & Power Platform Community Call on 23 July 2026. The session recording, slides and resources are on the talk page.




