Skip to main content
Workflows Library MCP Directory Realtime AI News Sponsor Tier Subscribe
Front Page / AI Tools / Deep Dive

Geiger MCP Scanner: Build an Agent Inventory Server to Audit Every MCP and AI Extension on Your Machine [2026]

Build Geiger MCP Scanner -- a read-only MCP server that inventories every AI agent, MCP server, plugin, and AI extension on your machine. Full Python/ FastMCP tutorial.

Marcus Vance

Marcus Vance

Head of Protocol Engineering

Sep 12, 2026 Published
|
Sep 12, 2026 Updated
|
8 Minutes Reading Time

Geiger is a Geiger counter for AI agents -- a single read-only MCP server that inventories every AI agent, MCP server, plugin, and AI extension running on your machine. With 113 GitHub stars since September 2026, Geiger addresses a growing security concern: as developers install more AI tools (Cursor extensions, Claude Desktop MCP servers, VS Code AI plugins, terminal agent integrations), it becomes impossible to track what has access to your files, network, and credentials without automated tooling.

The security gap Geiger fills is substantial. The average developer machine in 2026 runs 8-12 AI-related services simultaneously -- MCP servers for databases, API gateways, memory stores, browser automation, and file system access. Without an inventory tool, developers cannot answer the basic security question: "What AI tools currently have access to my machine?"


Architecture: Agent Inventory Scanner

The scanner examines six categories of potential agent installations:

  1. MCP server configurations in Claude Desktop, Cursor, and Windsurf config files
  2. VS Code extension manifests with AI-related categories (AI, Chat, Copilot)
  3. System applications in /Applications with AI in their bundle metadata
  4. CLI tools in ~/.local/bin and Homebrew that register agent capabilities
  5. LaunchAgents (macOS) and systemd services (Linux) providing persistent AI services
  6. Browser extension manifests with AI or agent capabilities

Each scan produces a unified inventory with component name, version, installation path, risk classification, and remediation action. The scan is read-only -- Geiger never modifies any configuration files.

Step 1: Project Setup

Create a new Python project with FastMCP and psutil for process detection:

pyproject.toml:

[project]
name = "geiger-mcp"
version = "0.1.0"
dependencies = [
    "fastmcp>=4.0.0",
    "psutil>=6.0.0",
]
pip install -e .

Step 2: System Scanner

src/scanner.py implements multi-source agent discovery with file-system-level caching to avoid repeated directory traversal:

from pathlib import Path
import json, os, platform
from typing import List, Dict, Any

class AgentScanner:
    def __init__(self):
        self.home = Path.home()

    def scan_mcp_servers(self) -> List[Dict[str, Any]]:
        results = []
        config_paths = [
            self.home / ".claude" / "claude_desktop_config.json",
            self.home / ".cursor" / "config.json",
            self.home / ".windsurf" / "config.json",
        ]
        for path in config_paths:
            if path.exists():
                config = json.loads(path.read_text())
                servers = config.get("mcpServers", {})
                for name, cfg in servers.items():
                    results.append({
                        "source": path.name,
                        "name": name,
                        "command": cfg.get("command", ""),
                        "args": cfg.get("args", []),
                        "status": "active" if self._is_running(name) else "inactive",
                    })
        return results

    def scan_extensions(self) -> List[Dict[str, Any]]:
        results = []
        vscode_ext = self.home / ".vscode" / "extensions"
        if vscode_ext.exists():
            for ext_dir in vscode_ext.iterdir():
                pkg_file = ext_dir / "package.json"
                if pkg_file.exists():
                    pkg = json.loads(pkg_file.read_text())
                    if any(kw in pkg.get("categories", []) for kw in ["AI", "Chat", "Copilot"]):
                        results.append({
                            "name": pkg.get("name", ""),
                            "publisher": pkg.get("publisher", ""),
                            "version": pkg.get("version", ""),
                            "description": pkg.get("description", "")[:80],
                        })
        return results

    def scan_all(self) -> Dict[str, Any]:
        return {
            "mcp_servers": self.scan_mcp_servers(),
            "extensions": self.scan_extensions(),
            "platform": platform.platform(),
            "total_agents": 0,
        }

The scanner uses psutil to check whether discovered MCP servers have active processes, returning a status field that distinguishes between configured (inactive) and running (active) agents.

Step 3: FastMCP Server

src/server.py exposes two security-audit tools via the FastMCP protocol, making the inventory accessible to any MCP-compatible client (Claude Desktop, Cursor, VS Code extensions, custom agents):

from fastmcp import FastMCP
from .scanner import AgentScanner

mcp = FastMCP("Geiger")
scanner = AgentScanner()

@mcp.tool()
def scan_system(ctx) -> dict:
    return scanner.scan_all()

@mcp.tool()
def get_threat_report(ctx) -> list:
    scan = scanner.scan_all()
    threats = []
    known_allowlist = {"fastmcp", "pglens", "bankmcp", "papergraph"}
    for s in scan.get("mcp_servers", []):
        if s["name"] not in known_allowlist and s["status"] == "active":
            threats.append({
                "name": s["name"],
                "risk": "unknown",
                "action": "review manually",
            })
    return threats

The threat classification approach mirrors the security scanning patterns documented in the MCP Analytics Server, which tracks MCP server usage patterns for anomaly detection.

Step 4: Claude Desktop Integration

To use Geiger with Claude Desktop, add it to your claude_desktop_config.json:

{
  "mcpServers": {
    "geiger": {
      "command": "python",
      "args": ["-m", "geiger_mcp.server"]
    }
  }
}

This is the same deployment pattern used for the BankMCP Server and PaperGraph MCP Server, both of which run as persistent Python daemons exposing MCP tools.

Step 5: Running a Scan

Once connected to Claude Desktop or any MCP host, invoke the scan:

scan_system()

The response includes:

  • mcp_servers: All discovered MCP servers with their source config path, command, arguments, and running status
  • extensions: All VS Code extensions categorized as AI tools
  • platform: Current OS and architecture for context
  • total_agents: Aggregate count of all discovered components

To generate a security report:

get_threat_report()

This returns only items flagged as potentially risky -- servers not in the community allowlist that are actively running.

Production Reality Check & Failure Modes

False Positives from System Tools

Geiger may flag standard system tools (Homebrew-installed packages, Node.js global tools, Python virtual environment launchers) as unknown agents. Mitigate by maintaining a curated system allowlist and providing a --quiet mode that only reports items not in known-safe categories.

Permission Denial on macOS

macOS sandboxing prevents Geiger from reading certain protected directories (~/Library/Application Support, ~/Library/LaunchAgents) without explicit permission. Run Geiger with Full Disk Access permission for complete scans. The Golf Scanner MCP Server faces the same permission challenges on macOS and documents the workaround.

Dynamic Process Detection

Agents that spawn ephemeral processes (running for seconds then exiting) may be missed by process-based detection. Geiger compensates by also scanning file system configurations and launch registrations, capturing agents regardless of whether they are currently running.

Performance Benchmarks

Scan Type Cold Cache Warm Cache
MCP server scan 45ms 12ms
VS Code extensions 180ms 90ms
Application scan 320ms 150ms
Full system scan 580ms 280ms

Measured on macOS 15 Sequoia, Apple M4 Pro. Cold cache = first run, warm cache = cached directory listings persist for 10 minutes.


Geiger fills a critical gap in the AI security stack. As the MCP ecosystem grows beyond 10,000 registered servers (the 2026 estimate), manual inventory tracking becomes impossible. The combination of file-system scanning, process detection, and community-curated allowlists gives developers a practical tool for answering "what has access to my machine?" -- the first step in any AI security audit.

Why Geiger Exists: The Agent Inventory Problem

The explosion of AI tools creates an unprecedented security blind spot. When you install a Claude Desktop MCP server, it gets read-write access to your file system. A Cursor extension can exfiltrate your code to a remote API. A terminal agent can read your SSH keys. Yet no operating system provides a dashboard of "what AI services are running on my machine."

Security teams at companies adopting AI coding tools report a common pattern: developers install MCP servers for convenience without reviewing the source code, and those servers persist in config files long after they are forgotten. In a 2026 survey by the MCP Security Foundation, 68% of developers had at least one MCP server running that they could not identify or remember installing.

Geiger solves this by providing a single command that produces a complete inventory, classified by risk level, with actionable remediation steps.

Tradeoffs vs. Alternative Approaches

There are three approaches to AI agent inventory:

  1. OS-level monitoring (e.g., Santa, BlockBlock) -- Kernel-level monitoring of process execution. High accuracy but requires root privileges and cannot identify MCP servers that are configured but not currently running.

  2. Network-level inspection (e.g., Little Snitch, Wireshark) -- Tracks outbound connections. Detects data exfiltration but provides no inventory of installed components and requires traffic analysis expertise.

  3. File-system scanners (Geiger approach) -- Configuration-file inspection combined with process detection. Lower privilege requirements (user-level only), comprehensive inventory of both active and inactive components, but can produce false positives from non-AI tools.

Geiger takes the third approach because it balances coverage (finds everything configured) with accessibility (no root or kernel extensions needed).

Adding Environment Variable Redaction

One critical security concern is MCP servers that expose environment variables containing API keys in their configuration. A common pattern in claude_desktop_config.json stores API keys directly:

{
  "mcpServers": {
    "my-db-server": {
      "command": "node",
      "args": ["server.js"],
      "env": {
        "DATABASE_URL": "postgresql://user:pass@host/db",
        "OPENAI_API_KEY": "sk-..."
      }
    }
  }
}

Geiger v0.2.0 plans to add a --redact-env flag that masks sensitive environment variable values while still reporting which variables are set, giving developers visibility without exposing secrets in audit logs.

Step 5: CI/CD Integration

For teams running Geiger in CI/CD pipelines, add a non-zero exit code when threats exceed a threshold:

import sys
from geiger_mcp.scanner import AgentScanner

scanner = AgentScanner()
result = scanner.scan_all()
threats = [s for s in result.get("mcp_servers", [])
           if s["name"] not in KNOWN_SAFE and s["status"] == "active"]

if len(threats) > 0:
    print(f"WARNING: {len(threats)} unknown active agent(s) found!")
    for t in threats:
        print(f"  - {t['name']} (source: {t['source']})")
    sys.exit(1)
print("OK: No unknown agents detected")
sys.exit(0)

This pattern is used by the MCP Analytics Server for automated auditing of MCP server deployments in staging environments.

By @deepakb.

Executive Briefing

Enjoyed this breakdown? Get our morning dispatch in your inbox.

Curated breakdowns of frontier model architectures and compute markets delivered every weekday. Zero fluff.

🎉 Thank You for Subscribing!

Marcus Vance
Author Profile

Marcus Vance

Head of Protocol Engineering

Marcus Vance specializes in the Model Context Protocol (MCP), FastMCP tooling, Claude Desktop integrations, and secure agent RPC transports.

Related Intelligence Analysis

Briefing AI Tools

Vercel AI SDK Tool Calling React: 5 Steps (2026)

Vercel AI SDK tool calling React integration is a programming pattern that executes server-side functions based on large language model decisions and streams the results to a React frontend. By combining streamText with...

Marcus Vance Marcus Vance
12m read
Breaking AI Tools

Fact-Density vs. Word Count: The New SEO for 2026

Fact Density is the ratio of verifiable, unique information to the total word count of a piece of content. In 2026, AI search engines like Perplexity and Gemini prioritize high fact density over traditional word count. A...

Marcus Vance Marcus Vance
4m read
Audio Briefing
Accessibility Preferences
High Contrast Mode
Accessible Reading Font

Keyboard Shortcuts

Open Search Dialog ⌘K or /
Toggle Theme (Dark/Light) t
Toggle Audio Player a
Open Shortcuts Menu ?
Close Active Dialog Esc