Installed AI software
The collector’s network observation sees software while it talks to an AI provider. This scan sees what is installed or configured whether or not it is in use today: the model runtime nobody has started yet, the coding extension added last week, the MCP server wired into a desktop assistant. Everything it finds appears in the AI inventory as Installed, beside what is Seen in use.
It is on by default. Turn it off for an environment under Settings → Collection & deployment → Collection policy → Installed AI software, or for one person under Discover → AI usage → People (see Collection policy).
What is found
Section titled “What is found”| Kind | macOS | Windows | Linux |
|---|---|---|---|
| Apps | /Applications (and one folder level below), each person’s ~/Applications; matched on the bundle’s CFBundleIdentifier | Uninstall registry keys (HKLM, its 32-bit view, HKCU, and each signed-in person’s hive when the collector runs as a service), matched on the executable the entry’s icon names; per-user installs under %LOCALAPPDATA%; Store apps by package name | Desktop entries (system, per-user, Flatpak and Snap exports) by file id; /snap by snap name |
| Command-line agents | claude, codex, gemini, aider, cursor-agent, lms, ollama in /usr/local/bin, /opt/homebrew/bin, /usr/bin, ~/.local/bin, ~/.npm-global/bin, ~/.bun/bin, ~/bin | The same names under %APPDATA%\npm and ~/.local/bin | As macOS |
| Local model runtimes | Running processes (ps) and listening sockets (lsof) | Running processes and the listener table | /proc |
| Editor extensions | ~/.vscode, ~/.vscode-insiders, ~/.cursor, ~/.windsurf, ~/.vscode-oss and ~/.vscode-server extension folders; JetBrains plugins under ~/Library/Application Support/JetBrains | The same folders; JetBrains under %APPDATA%\JetBrains | The same folders; JetBrains under ~/.local/share/JetBrains |
| MCP servers | Claude Desktop, Claude Code (~/.claude.json and each project’s .mcp.json), Cursor, VS Code (and Insiders, VSCodium) mcp.json and settings, Cline, Windsurf, Gemini CLI, Codex and Zed | The same clients | The same clients |
Matching is exact: a bundle identifier, an executable or package name, a desktop-file id, an extension or plugin id, or a process name. Nothing is matched on a display name, so an app called “Claude Notes” is not reported as Claude. The collector’s built-in catalog is the fallback; the platform’s catalog, with your reviewers’ decisions, arrives with the device policy and is matched the same way. shield360 collector ai-software lists what it finds on a machine without sending anything (--all lists every installed app).
Every installed app, and the AI inside it
Section titled “Every installed app, and the AI inside it”Most AI on a computer is not in an app called AI. It is built into the note-taking app, the design tool, the meeting client, and into apps nobody has catalogued. So the scan reports every installed application (its name, identifier, publisher where Windows records one, and version) together with the AI found inside its own files:
| Looked at | What counts as AI |
|---|---|
An Electron app’s app.asar (its index only, at most 16 MB) and unpacked node_modules | AI SDK packages: openai, @anthropic-ai/*, @google/genai, @mistralai/*, cohere-ai, groq-sdk, the Vercel AI SDK (ai, @ai-sdk/*), LangChain, LlamaIndex, ONNX Runtime, Transformers.js, TensorFlow.js, ollama, replicate, the MCP SDK, Copilot SDKs and more |
The app’s own package.json and requirements.txt | The same packages, and Python’s (openai, anthropic, torch, transformers, llama_cpp, mlx…) |
Library file names (macOS Contents/Frameworks, Windows .dll, Linux .so) | ONNX Runtime, DirectML, Windows ML, llama.cpp / ggml, whisper.cpp, TensorFlow Lite, LibTorch, MLX, OpenVINO, CTranslate2, MediaPipe, Qualcomm QNN and more |
| Model file extensions | .gguf, .onnx, .tflite, Core ML (.mlmodel, .mlmodelc, .mlpackage), .safetensors, .pte |
What is reported is a list of signature IDs (npm:openai, lib:onnxruntime, model:coreml), never a path inside the app and never a file’s contents. Only the application’s own folder is looked at, never a person’s documents. Each app costs a bounded amount (at most 60,000 folder entries, six folders deep, and 24 MB read), and all of them together at most 10 seconds per scan; an app looked at before is not read again until it changes.
AI tool, AI built in, or not AI
Section titled “AI tool, AI built in, or not AI”The platform classifies each installed app once for the whole fleet, strongest first:
- A reviewer’s decision in this environment. It overrides the catalogue, for this environment only: set an app’s class on its page in the AI inventory (AI class), or decide an analyst finding about it. An organisation can make Grammarly an AI tool, or ChatGPT Not AI, without changing anyone else’s classification. The inventory marks such a class set here, lists every one under Classifications set in this environment (with what the catalogue says, and a reset), and the change is audited. Decisions reach the environment’s collectors with their policy.
- The AI catalogue. AI products (ChatGPT, Cursor) are AI tools. Ordinary apps with AI features (Notion, Slack, Zoom, Figma, Canva, Grammarly, the Microsoft 365 apps, Chrome, Edge, Arc, Adobe’s Firefly apps, Linear, Miro, ClickUp, Loom, Superhuman, Raycast, Obsidian, VS Code, Postman, Docker Desktop) are AI built in.
- AI found inside it. An app carrying an AI library, SDK or model is AI built in until a reviewer says otherwise.
- The AI analyst’s judgement of its name and identifier; a likely-AI app is raised as a finding for a reviewer.
AI tools and apps with AI built in appear in the AI inventory, the latter marked AI built in (filter by AI class). An app with AI built in is never counted as shadow AI for being installed or for the time spent in it; it appears there only when its process is seen reaching an AI provider. Shadow AI follows the environment’s classification: an app a reviewer made an AI tool is counted on its time like any AI tool, and one made AI built in or not AI is not.
Local model runtimes
Section titled “Local model runtimes”A runtime is found by its process name (Ollama, LM Studio, llama.cpp’s llama-server, vLLM, Jan, GPT4All, LocalAI, KoboldCpp, Msty) on whatever port it listens, or by a listening socket on its default port when the server there answers that runtime’s own API. On ports many servers share (8080, 8000, 5000) the answer itself must say which runtime it is.
The collector asks the runtime, on 127.0.0.1 only, for its version and the names of its models (Ollama’s /api/version and /api/tags, the OpenAI-compatible /v1/models), with a 1.5-second timeout and without any proxy. It never asks a server bound only to another interface, and never sends a prompt. The address the runtime listens on is reported, so a runtime open to the network (0.0.0.0:11434) is visible.
On-device AI in running applications
Section titled “On-device AI in running applications”Every ten minutes the collector also checks which running applications have AI inference loaded. This covers local models, apps’ built-in AI features and the operating system’s own, none of which reach the network. It reads the files each process has mapped, keeps only those that match a signature, and reports the application, the runtime and whether a model is loaded.
| Signature | Recognised by |
|---|---|
| ONNX Runtime, llama.cpp / ggml, whisper.cpp, CTranslate2, OpenVINO, PyTorch, TensorFlow, TensorFlow Lite, MLX | Their libraries (libonnxruntime, libllama, libggml-*, libtorch_cpu, libmlx…) |
| Local models | A mapped GGUF, ONNX, TensorFlow Lite or Safetensors file, or a compiled Core ML model |
| Core ML | A compiled model (.mlmodelc) mapped by an application. macOS’s own processes and Apple’s apps map these constantly and are not reported. |
| DirectML, Windows ML | Their DLLs (Windows) |
| CUDA (cuDNN, cuBLASLt) | Only alongside another runtime, because games and video tools load these too |
| Platform | Source | Without privilege |
|---|---|---|
| macOS | One lsof pass over mapped files (about 0.4 s for 500 processes) | The user’s own processes |
| Linux | /proc/<pid>/maps | The user’s own processes |
| Windows | Each process’s module list | The user’s own processes; only DLLs are visible, so a loaded model file is not |
Only signature ids and model formats are reported (for example llama.cpp, gguf), with the application’s name, bundle, signer and executable path. The home directory is written as ~. A model’s name, its path, and anything a model was asked never leave the machine. Each record appears in the AI inventory as On-device AI evidence, which counts as in use. It also appears on each person’s and computer’s page.
This check follows the Installed AI software setting and its kill switch.
What is reported, and what never is
Section titled “What is reported, and what never is”| Kind | Reported | Never reported |
|---|---|---|
| App (and every installed app) | Catalog id, bundle id or executable, name, vendor, version, install path with the home directory as ~, the IDs of AI signatures found inside it | The app’s files or their contents, paths inside it, anything in its data or a person’s documents |
| Runtime | Name, version, listen address, model names | Prompts, model files, anything a model was asked |
| Editor extension | Extension id, name, version, the editor | Extension settings or data |
| MCP server | The client, the name it was given, the transport, the command’s file name or the URL’s host | Arguments, environment variables, headers, tokens, the URL’s path, query or credentials, the command’s directory |
The platform checks the same on ingest: an MCP target that is a URL is cut to its host and a command to its file name, an install path in a home directory is written as ~, and fields that do not belong to an item’s kind are dropped, whatever an older or modified collector sends.
When it runs
Section titled “When it runs”- A full snapshot two minutes after the collector starts and every six hours. Each snapshot carries everything found, so something uninstalled simply stops appearing; the inventory shows when each install was last reported.
- A runtime check every ten minutes, which sends only when the runtimes found changed (one started, or gained or lost a model).
A full scan is bounded to 20 seconds (looking inside apps to 10 of them) and a runtime check to 5. Measured on a Mac with 46 apps, the first full scan took about 2 seconds and 33 MB of memory; later scans read only apps that changed. A machine on which three scans in a row run over turns scanning off until the collector restarts, as network observation does.
Stop it on one machine
Section titled “Stop it on one machine”Create the file the collector names in shield360 collector ai-software --help (by default ~/.config/shield360/disable-ai-software, or under %APPDATA%\shield360 on Windows). While it exists nothing is scanned, whatever the platform says. Delete it to scan again.
Storage
Section titled “Storage”Records go to shield360_collector_ai_software: one row per item, machine and person per day, kept for 365 days. Installed apps are rows of kind installed_app, with their signatures in the evidence column. On-device AI goes to shield360_collector_ai_runtimes on the same terms. They are personal data for data export and deletion, as every collector table is.