In my post on Microsoft Execution Containers, I looked at setting boundaries around an agent's work. Before you can decide where to apply those controls, you also need to know which agents people are running. That includes Claude Code in a developer's terminal, Cursor with six MCP servers wired in, or OpenClaw running on someone's laptop.
On 29 October 2026 Microsoft announced that local AI agent discovery in Microsoft Defender for Endpoint is generally available. It was introduced at Build with around 20 agent types, and the GA release claims 50+ agents across Windows and macOS, including their MCP server configurations. Runtime protection, which can actually block an agent's actions, is still preview and Windows only.
I went through the announcement, the Learn documentation and the support matrix line by line. The short version: discovery is useful and costs you nothing extra if you already run MDE P2, but the coverage is uneven, the risk scoring sits behind a higher license, and a few things in the docs don't agree with each other. Here's what I found.
Why Microsoft built this
A coding agent on an endpoint runs as the signed-in user. It reads the same files, uses the same cached tokens, and reaches the same internal systems the user can. In identity terms it doesn't exist; Microsoft Entra ID sees the user, not the agent. That's the gap I keep coming back to in this series. An agent with the user's privileges and no separate identity is effectively an agentic insider.
MCP widens the reach further. Every MCP server you add to an agent's config is a new set of tools:
a database connector, a GitHub server with a PAT in its config, a filesystem server pointed at the
home directory. Add autoApprove and the agent calls those tools without asking anyone.
Then add prompt injection: hidden text in a README or an issue comment that tells the agent to read
.env and post it to an external URL. The user never typed that instruction, but the
agent ran it with their credentials.
Traditional EDR sees node.exe or code.exe making network calls. It
doesn't know that the process is an agent, which model is behind it, or which tools it can call.
That context is what Microsoft is adding here. Before you can apply any policy, you need to know
which agents exist, where, under which user, and what they're connected to.
What's GA and what's still preview
The announcement headline says GA, but only part of the feature set is. This is the split as I read the announcement and the Learn pages together:
| Capability | Status | Platforms | Notes |
|---|---|---|---|
| Agent and MCP discovery | GA | Windows | About 60 agents in the support matrix |
| Agent and MCP discovery | Preview on Learn, GA in the announcement | macOS | About 51 agents, thinner MCP coverage |
| Agent discovery in WSL | Preview | Windows Subsystem for Linux | Three CLI agents, no MCP discovery |
| Risk level, risk indicators, recommendations | Available with E7 or Agent 365 | Windows, macOS | Not included in MDE P2 alone |
| Runtime protection (agent hooks) | Preview | Windows only | Six agent surfaces |
| Runtime protection (network inspection) | Preview | Windows only | Four agents, no certificate pinning or HTTP/3 |
| Runtime protection deployment through Intune | Preview | Windows | Profile covers hooks only |
| Native Linux | Not supported | None | WSL support doesn't extend to Linux servers or desktops |
Note: The Tech Community post says discovery is GA "on Windows and macOS", but the Learn prerequisites and the support matrix still label macOS as preview. I'd treat macOS as preview until the docs change, especially if you need to tell a customer what's covered by the support agreement.
How discovery actually works
There's nothing extra to deploy. In the commercial cloud, if the device is onboarded to MDE,
Microsoft Defender Antivirus is in active mode with real-time protection on, and the platform and
engine updates are current, discovery starts on its own when a supported agent runs. The results
land in the Defender portal under Assets > AI agents > Local agents and in
the AgentsInfo table in advanced hunting. Sovereign and national clouds aren't supported.
Two design decisions matter more than anything else on the feature page:
- Discovery is activity-based. An agent shows up only after Defender sees it running. An agent installed six months ago and never launched won't appear. Microsoft says this directly: it isn't a software inventory, and for installed-but-idle tools you should use the Defender Vulnerability Management software inventory instead.
- One inventory entry is one user, on one device, running one agent type. Claude Code used in 15 project folders by the same person on the same laptop is a single entry. The same agent used by two people on a shared jump host is two entries. In the portal list, an agent used across many devices appears many times, which is why the KQL view below is more useful for counting.
Each entry carries the agent name and version, device, OS, account, the number of MCP servers and
local MCPs, and first-seen time. The details pane adds the vendor, the model when it can be read,
the related host process, whether that host process is trusted, and whether
autoApprove is on. From there you can go to hunting, open the agent on the exposure
map, or open the agent page.
Licensing and what it costs
The basic inventory comes with Defender for Endpoint Plan 2, so for most E5 shops this is already paid for. The parts that turn an inventory into a prioritised list don't.
| Feature | MDE P2 (also in M365 E5) | M365 E7, or Agent 365 + P2 |
|---|---|---|
| Local agents inventory and agent details | Yes | Yes |
| MCP servers per agent | Yes | Yes |
Advanced hunting with AgentsInfo |
Yes | Yes |
| Risk level, risk indicators, recommendations | No | Yes |
| Runtime protection (preview) | Listed for P2, E5, Agent 365 or E7 | Yes |
The risk indicators are things like "Running on a Critical Device" and "Used by a Critical User". You can query local agents and device criticality in the exposure graph, as shown below, if that data is available in your tenant. The query isn't a replacement for the complete risk score or recommendations. If you're on E5 and someone proposes E7 just for the risk column, check which indicators you need and whether the gap is worth the price.
One cost that doesn't show on a license sheet: runtime protection in preview expects test devices on the Beta Channel for platform and engine updates. That's a separate update ring to run and support, not just a policy toggle.
What works well
- There's no extra deployment once the prerequisites are met. You don't need a new agent, browser extension or proxy, and supported agent activity can appear in the inventory automatically.
- MCP visibility is the part I find most valuable. Seeing which MCP servers each agent uses, including local MCPs
and the command that starts them, matters. A local MCP launched with
npx some-package@latestis a supply chain question nobody was asking until now. autoApproveandtrustedProcessare two simple fields that answer "can this agent act without a human?" and "is the host process what it claims to be?". Those are the first two questions I'd ask during an incident.- The exposure graph integration turns agents into nodes with
runs on,usesandused byedges, so you can see the blast radius: an agent with auto-approve, on a device tagged critical, used by a Global Administrator. - On P2 the raw data is already in advanced hunting without the higher license, so you can build your own reports, custom detections and workbooks.
- Windows coverage is broad. The matrix covers CLI agents (Claude Code, Codex CLI, Gemini CLI, Copilot CLI), desktop apps (ChatGPT, Claude, Ollama, Perplexity), IDEs (Cursor, Kiro, Antigravity, Windsurf), VS Code extensions (Cline, Roo Code, Copilot, Claude Code) and the Claw family (OpenClaw, Clawpilot, QClaw). That's a decent picture of what developers actually install.
Where it falls short
Discovery only sees what runs
Because discovery is activity-based, your inventory is really a "recently used" list. That's fine for risk (an agent that never runs doesn't do much damage) but it's misleading if someone reads the count as "agents installed in the estate". Pair it with the software inventory for installed applications, and remember that npm-installed CLI agents won't always show up there either.
Linux is mostly missing
There's no native Linux support at all. WSL is in preview with only three agents (Claude Code, Codex CLI and GitHub Copilot CLI), and none of them get MCP discovery in WSL. Many developers run agents inside dev containers, Codespaces or Linux build hosts. None of that is in scope. If your platform engineers live in Linux, this inventory will undercount exactly the people with the most access.
MCP coverage has holes
The agent list is long, but MCP config discovery isn't available for every agent. On Windows the matrix lists no MCP discovery for Amp CLI, Cline CLI, Devin CLI, Goose, Grok, Kilo, LM Studio, Ollama Desktop, Perplexity, Qwen, Trae, Clawpilot, QClaw and several more. On macOS the list is longer and includes Antigravity, Kiro, Roo Code and Windsurf. Ollama Desktop is the odd one out: it gets MCP discovery on macOS but not on Windows. So an agent showing "0 MCP servers" may mean none are configured, or that Defender can't read the config for that agent on that OS. Check the matrix before you report numbers.
Runtime protection covers a short list
Discovery covers around 60 agents. Runtime protection covers about ten, and only on Windows:
- Agent hooks (agent-native inspection): Claude Code, GitHub Copilot CLI, the GitHub Copilot app, Claude Desktop in Code mode, and the GitHub Copilot and Claude Code extensions in VS Code.
- Network inspection: OpenClaw, Ollama Desktop, ChatGPT Classic and ChatGPT Desktop in Chat mode (minimum tested version 26.810.52044).
Cursor, Windsurf, Gemini CLI and Kiro have discovery but no runtime protection. Network inspection also doesn't work when the agent uses certificate pinning or HTTP/3, which is where a lot of client software is heading. I'd treat network inspection as best effort and hooks as the real control.
The docs disagree with each other
Two inconsistencies I ran into. The runtime protection overview mentions Codex CLI as a hooks-capable agent, but the support matrix doesn't list Codex for runtime protection at all. And as covered above, macOS discovery is GA in the announcement and preview on Learn. The support matrix page is also marked as AI-generated in its metadata and one entry (Qwen Code Desktop) has no vendor. None of this is a blocker, but test on your own devices before you promise coverage to anyone.
Smaller things worth knowing
- Commercial cloud only. Government, sovereign and national clouds aren't supported.
- The Intune and Defender portal profile only configures agent hooks. Network inspection needs a PowerShell platform script, and Intune runs that script once unless you change it.
- Devices managed through security settings management without Intune enrollment need policy assigned to Microsoft Entra device groups. User targeting isn't supported.
- Users have to close and reopen their terminals before agents pick up the runtime setting.
- Reinstalling an agent can create a new
AgentIdand mark the old one as Deleted, so naive counts over time will double up.
Turning on runtime protection
Runtime protection watches tool calls and tool responses. The example Microsoft uses is the one I
described at the start: documentation with hidden text telling the agent to read .env
and send it out. With Block on, Defender stops it at the tool
response and raises a "Suspicious AI prompt injection" alert. Audit mode raises an Informational
alert instead. Block raises an alert with severity based on assessed risk, and the user sees a
message in the agent terminal, a Windows toast and an entry in Protection history.
First check the security intelligence version on a test device. It needs to be 1.451.224.0 or later:
# Security intelligence must be 1.451.224.0 or later
Get-MpComputerStatus | Select-Object AntivirusSignatureVersion
# Agent hooks (agent-native inspection): Audit, Block or Disabled
Set-MpPreference -AiAgentProtection Audit
# Network inspection for agents without hooks: Audit, Block or Disabled
Set-MpPreference -AiAgentNetworkInspection Audit
# Confirm both settings
Get-MpPreference | Select-Object AiAgentProtection, AiAgentNetworkInspection
For more than a handful of devices, use the Microsoft Defender AI agent runtime
protection profile in Intune or the Defender portal for agent hooks. For network
inspection, wrap the Set-MpPreference -AiAgentNetworkInspection line in an Intune
PowerShell platform script that runs as system, with "Run this script using the logged on
credentials" set to No. Verify the result on the device page under Configuration management
> Effective settings. Tamper protection guards the setting once applied.
Important: Microsoft recommends Audit for one to two weeks before Block. I'd follow that. Coding agents read untrusted text all day (issues, docs, web pages), and you want to see the false positive rate on your own repositories before a developer's build agent stops mid-task.
Microsoft also publishes a runtime protection demonstration page with a benign test string. Point a supported agent at it in Audit mode and confirm the alert reaches the portal before you roll out further.
Hunting queries I'd start with
AgentsInfo writes a new record every time an agent profile changes, so take the
latest record per AgentId and filter out Deleted and Uninstalled. This inventory
query is based on the Learn example and counts devices separately from agent profiles.
There's a field-name mismatch in Microsoft's documentation: the table schema lists AgentName, while the local discovery examples use Name. These
queries use AgentName. If your hunting schema exposes Name instead,
replace that column in both queries and check the results against your inventory.
AgentsInfo
| where Platform == "LocalAgents"
| summarize arg_max(Timestamp, AgentName, Version, LifecycleStatus, RawAgentInfo) by AgentId
| where LifecycleStatus !in~ ("Deleted", "Uninstalled")
| extend AgentMetadata = RawAgentInfo.localAgentMetadata
| extend Vendor = tostring(AgentMetadata.vendor),
Process = tostring(AgentMetadata.relatedProcess),
Device = tostring(AgentMetadata.deviceName),
Account = tostring(AgentMetadata.accountName)
| summarize Installations = count(),
DeviceCount = dcount(Device),
Versions = make_set(Version, 20),
Accounts = make_set_if(Account, isnotempty(Account), 50)
by Agent = AgentName, Vendor, Process
| sort by DeviceCount desc, Installations desc
Next, the agents that can act on their own or run in an untrusted host process. Note that
autoApprove and trustedProcess are strings, so compare them to
"true" and "false" rather than using tobool():
AgentsInfo
| where Platform == "LocalAgents"
| summarize arg_max(Timestamp, AgentName, Version, LifecycleStatus, RawAgentInfo) by AgentId
| where LifecycleStatus !in~ ("Deleted", "Uninstalled")
| extend AgentMetadata = RawAgentInfo.localAgentMetadata
| extend AutoApprove = tostring(AgentMetadata.autoApprove),
TrustedProcess = tostring(AgentMetadata.trustedProcess),
Process = tostring(AgentMetadata.relatedProcess),
Device = tostring(AgentMetadata.deviceName),
Account = tostring(AgentMetadata.accountName)
| where AutoApprove =~ "true" or TrustedProcess =~ "false"
| project Timestamp, Agent = AgentName, Version, Device, Account, Process, AutoApprove, TrustedProcess
| sort by AutoApprove desc, Device asc
Finally, use the exposure graph to find local agents on devices with a high or very high criticality classification. Edges carry no local-agent flag, so resolve the local agent nodes first and join on their node IDs. Criticality level 0 is the highest; the query includes levels 0 and 1. This covers one condition, not the full paid risk assessment.
let LocalAgentNodes = ExposureGraphNodes
| where NodeLabel == "ai-agent"
| where tostring(NodeProperties.rawData.aiAgentMetadata.platform) == "LocalAgents"
| project AgentNodeId = NodeId, AgentName = NodeName,
AgentId = tostring(NodeProperties.rawData.aiAgentMetadata.id);
let CriticalDevices = ExposureGraphNodes
| where NodeLabel in~ ("device", "ec2.instance", "microsoft.compute/virtualmachines")
| extend Criticality = toint(NodeProperties.rawData.criticalityLevel.criticalityLevel)
| where Criticality between (0 .. 1)
| project DeviceNodeId = NodeId, DeviceName = NodeName, Criticality;
ExposureGraphEdges
| where EdgeLabel =~ "runs on"
| join kind=inner (LocalAgentNodes) on $left.SourceNodeId == $right.AgentNodeId
| join kind=inner (CriticalDevices) on $left.TargetNodeId == $right.DeviceNodeId
| project AgentName, AgentId, DeviceName, Criticality
| sort by Criticality asc, DeviceName asc
Swap runs on for used by and point the second join at user nodes to get
the same view for critical accounts. The Learn page has a longer MCP query that unions remote
servers, local MCPs and declared tools; I'd copy that one as is rather than rewrite it.
How I'd roll this out
- Confirm device health first. Discovery depends on Defender Antivirus in active mode with real-time protection and current updates. Devices running a third-party AV with Defender in passive mode won't report agents, so check that before trusting the numbers.
- Run the inventory and risky-config queries for two weeks. You'll learn which agents people actually use, which is usually more than the approved list.
- Review MCP servers with the owners. Local MCPs launched from public package registries and remote MCPs with tokens in config files are the first conversations to have.
- Decide on
autoApprovepolicy. Defender reports it, but it doesn't change it. That's a developer tooling setting you'll need to manage through the agent's own config or your endpoint configuration tooling. - Pilot runtime protection in Audit on a Beta Channel test ring, using the agents in the runtime list. Use the demonstration page to prove alerts flow.
- Move to Block for the supported agents after reviewing the Audit alerts. Keep in mind that agents without runtime coverage (Cursor, Windsurf, Gemini CLI, Kiro and anything in Linux) still need other controls, such as the containment approaches in my MXC post.
Discovery won't stop anything by itself, and it doesn't give agents an identity of their own. What it does well is answer the question I hear in nearly every security review now: which AI agents are running on our endpoints, under whose account, and with what tools. For P2 customers that answer is already in the portal, and you can start querying it today.
References
- Now generally available: Discover local AI agents with Microsoft Defender | Microsoft Tech Community
- AI agent support matrix | Microsoft Learn
- Local AI agent discovery overview | Microsoft Learn
- Discover local AI agents with Microsoft Defender for Endpoint | Microsoft Learn
- AI agent runtime protection overview | Microsoft Learn
- Configure AI agent runtime protection | Microsoft Learn
- AgentsInfo table in advanced hunting | Microsoft Learn