What the Scan Agent does
The Willow Scan Agent is a background service on macOS and Windows. Beyond discovering AI tools, it applies your organization's policy on the device, installs guard and telemetry hooks into supported coding agents, and keeps itself up to date.
This page lists each responsibility, what it touches on the machine, and what controls it. To install the agent, see Deploy Scan Agent with MDM or Install the Scan Agent manually.
| Responsibility | On by default | Controlled from |
|---|---|---|
| Discover AI tools | Yes | Always on |
| Extended discovery | No | Enabled per organization |
| Report to Willow | Yes | Always on |
| Enforce policy rules | When rules are published | Policy Rules |
| Provision guard hooks | No | AI Discovery > Settings |
| Configure agent telemetry | No | Admin > Settings > Log Settings > Collect Agent Telemetry |
| Optimize agent tokens | No | Enabled per organization |
| Update itself | Yes | Agent Updates on the Devices tab |
| Show device status | Yes | hideMenubar in the agent configuration |
The agent reads its feature settings from Willow on every cycle, so dashboard changes reach devices on their next scan without redeploying anything.
Discover AI tools
On every cycle the agent scans each user's home directory and project folders for four kinds of AI capability.
| Capability | What the agent looks for |
|---|---|
| MCP servers | MCP configuration in Claude Desktop, Claude Code, Cursor, VS Code and VS Code Insiders, Cline, Roo Code, Windsurf, Zed, Gemini CLI, Antigravity, Kiro, Amazon Q, Codex, OpenCode, Trae, Junie, and GitHub Copilot for IntelliJ. Both global and per-project files are read. |
| Skills and plugins | SKILL.md skill folders for about 40 coding agents, including Claude Code, Cursor, Codex, Windsurf, GitHub Copilot, Gemini CLI, Cline, Roo Code, and Pi. Claude Code, Cursor, and Codex plugins (plugin.json) are also collected, with their bundled commands, agents, rules, and hooks. |
| Agent memory | CLAUDE.md, CLAUDE.local.md, and AGENTS.md, both global and per project. |
| AI agents | Installed coding agents and AI apps, detected by their configuration folders. Examples include Claude Code, Claude Desktop, Cursor, Codex, GitHub Copilot, Windsurf, Gemini CLI, Ollama, and Perplexity. On macOS, the agent also reports whether Apple Intelligence is enabled. |
For skills and plugins, the agent uploads file contents so reviewers can read what a skill does. Identical files are uploaded once and deduplicated across devices.
Extended discovery
These scans are off by default and are turned on per organization.
| Scan | What it adds |
|---|---|
| Containers | AI-related Docker containers and images, Docker Desktop AI features and its MCP Toolkit, and AI tools declared in devcontainer.json or Docker Compose files. Running containers are read on macOS only. |
| Processes | Running MCP servers and AI processes, such as local model servers. macOS only. |
| WSL | MCP servers configured inside WSL distributions on Windows. These are reported but not enforced. |
| Agent settings | The full settings files of installed AI agents. Secret values are replaced with hashes, and cached credentials are removed. |
| Token usage | Daily token counts per model, read from Claude Code session transcripts. Uploaded at most once an hour. |
Report to Willow
Each cycle ends with a report to your Willow organization. The report contains the device identity, the signed-in user, and every capability found. The results then appear in the AI Discovery dashboard.
The agent protects secrets before anything leaves the machine:
- Environment variables and headers in MCP server entries are masked by default.
- Arguments that look like secrets are always redacted.
- Command lines from processes and containers are always redacted.
- For AI agents, only a fixed allow-list of non-sensitive configuration fields is kept.
The agent keeps its reporting light:
- A full scan runs once every 24 hours, and a quick shallow scan runs every 5 minutes.
- In between, the agent reuses cached results and skips the upload if nothing changed.
- It still reports at least once a day, so an idle device keeps showing as active.
A few things force a full scan and report right away:
- Sync Now in the menu bar app.
- A resync requested from Willow.
- The agent restarting after an interrupted update.
Enforce policy rules
When you publish Policy Rules, Willow returns each device's enforcement decisions in the response to its report. The agent then applies them to the files it discovered.
| Action | What happens on the device |
|---|---|
| Allow | Nothing changes. If the capability was blocked before, the agent restores its original configuration. |
| Warn | Nothing changes on disk. The agent records the warning in its log. |
| Block | For an MCP server, the agent rewrites the entry to point at a local Willow endpoint and keeps the original configuration inside the entry. When the AI client connects, it gets a message that the server is blocked by policy, with a link back to Willow. For a skill, SKILL.md is renamed to SKILL-blocked.md and replaced with a stub that explains the block. For a plugin, plugin.json is renamed to plugin-blocked.json and replaced with an empty stub, which turns off its hooks, commands, and MCP servers. |
| Managed | The agent swaps an unmanaged MCP server entry for its managed Willow gateway equivalent and keeps the original so it can be restored. |
Blocking is reversible. When a rule is removed or changed to allow, the agent restores the original file on its next cycle.
Provision guard hooks
When guards are enabled under AI Discovery > Settings, the agent installs Willow guard hooks into each user's coding agents. The hooks send agent events to Willow for evaluation before the agent acts, and apply the result, for example blocking a tool call.
| Coding agent | Where the hook is installed |
|---|---|
| Claude Code | ~/.claude/settings.json |
| Cursor | ~/.cursor/hooks.json |
| Codex | ~/.codex/hooks.json |
| Pi | A Willow extension in ~/.pi/agent/extensions/willow/ |
Willow decides which events each hook covers, so you can change coverage from the dashboard without touching devices.
Guard hooks fail open. If Willow can't be reached or doesn't answer within the timeout, the agent's action is allowed, so a network problem never stalls a developer's session.
The agent only edits the entries it owns and leaves your own hooks in place. When guards are turned off, it removes its entries and leaves the files themselves in place.
Configure agent telemetry
When telemetry collection is on for an agent under Admin > Settings > Log Settings > Collect Agent Telemetry, the Scan Agent points that agent's telemetry at Willow. The data then appears in Analytics.
| Coding agent | What the Scan Agent configures |
|---|---|
| Claude Code | The native OpenTelemetry exporter in ~/.claude/settings.json, plus a session hook that adds git repository context |
| Codex | The native [otel] section in ~/.codex/config.toml |
| Cursor | A Cursor hook that buffers events locally. The Scan Agent uploads them in batches, with repository context. |
| GitHub Copilot | The machine-wide Copilot managed settings, and the exporter environment for Copilot CLI |
| Pi | The Willow Pi extension |
A few settings shape where the data goes and what it contains:
- Your own collector: if you use an OTLP proxy, the agent sends telemetry to your collector instead of directly to Willow.
- Third-party collectors: if an agent already exports to a collector that isn't Willow's, the Scan Agent leaves that configuration alone.
- Prompt content: when content redaction is on in Log Settings, prompt text is left out.
Optimize agent tokens
When the Willow Optimizer is enabled for a device, the agent installs optimizer hooks into Claude Code, Cursor, and Codex. The hooks compress verbose tool output before it reaches the model, and can route prompts to a different model when routing is configured. Like guard hooks, they fail open, and the agent removes them when the Optimizer is turned off.
Update itself
Agents keep themselves current, so you deploy the package once. Control the target from the Agent Updates card on the Devices tab:
- Track the latest release.
- Pin a specific version.
- Turn automatic updates off.
The agent checks for a new release every few hours. Before installing one, it runs three checks:
- It verifies the release manifest's signature.
- It verifies the download's SHA-256 checksum.
- On macOS, it confirms the package is signed and notarized by Apple.
To keep one machine on its installed version, set autoUpdate to false in that device's agent configuration.
Show device status
The agent ships with a menu bar app on macOS and a system tray app on Windows. It shows:
- Whether the device is secured.
- When the last scan ran.
- Which skills and MCP servers are blocked.
It also offers Sync Now and a shortcut to Willow. Set hideMenubar to true in the agent configuration to keep it from launching.