# ProcmonMCP

> An MCP server for procmon

- **Type:** MCP server
- **Install:** `agentstack add mcp-jamezuk-procmonmcp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [JameZUK](https://agentstack.voostack.com/s/jamezuk)
- **Installs:** 0
- **Category:** [Integrations](https://agentstack.voostack.com/c/integrations)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [JameZUK](https://github.com/JameZUK)
- **Source:** https://github.com/JameZUK/ProcmonMCP

## Install

```sh
agentstack add mcp-jamezuk-procmonmcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# ProcmonMCP

ProcmonMCP is a [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that allows LLMs to autonomously analyse **Process Monitor (Procmon) XML log files**. It exposes a comprehensive set of analysis tools to any MCP-compatible client, including Claude Code, Claude Desktop, Cline, and others.

## Overview

Process Monitor captures detailed system activity — file access, registry operations, network connections, process creation, and more. ProcmonMCP parses these XML logs into an optimised in-memory representation and exposes them as MCP tools, enabling an LLM to investigate system behaviour without manual data wrangling.

Key capabilities:
- **Load files at runtime** — no need to restart the server to analyse a different capture
- **Parsed-capture cache** — reloading an unchanged file is near-instant (parsing is skipped)
- **String interning** for reduced memory footprint on large logs
- **Indexed lookups** by process name, operation, PID, and file path for fast filtering
- **Multiple transport protocols** — stdio (recommended), Streamable HTTP, and SSE (deprecated)
- **Progress feedback** during file loading via MCP notifications

This project was inspired by the approach taken in [GhidraMCP](https://github.com/LaurieWired/GhidraMCP).

> **Security Warning**
>
> Process Monitor logs can contain extremely sensitive system information (keystrokes, passwords in command lines, file contents, network traffic details, etc.).
>
> - This tool loads **any file path** that the user running the script has read permissions for. There is **no** directory sandboxing.
> - **Only run this server in trusted environments.**
> - **Never run this server with Procmon logs captured from systems containing sensitive production or personal data unless you fully understand and accept the risks.**
> - **Review the logs you intend to load for sensitive information before using this tool.**

## Installation

### Prerequisites

- Python 3.7 or newer (developed and tested with 3.10+)
- `pip` (Python package installer)

### Install from source

```bash
git clone https://github.com/JameZUK/ProcmonMCP
cd ProcmonMCP
pip install -r requirements.txt
```

Or install the package itself (provides a `procmon-mcp` console script):

```bash
pip install .            # core only (mcp[cli])
pip install ".[all]"     # core + optional lxml and psutil
pip install -e ".[dev]"  # editable install with test tooling
```

### Dependencies

| Package | Required | Purpose |
|---------|----------|---------|
| `mcp[cli]>=1.8.0` | Yes | MCP SDK with CLI tools and Streamable HTTP support |
| `lxml>=4.9.0` | Recommended | Faster XML parsing (falls back to stdlib `ElementTree` if absent) |
| `psutil>=5.9.0` | Optional | Memory usage reporting after file loading |
| `google-re2` | Optional | Linear-time, ReDoS-safe engine for user filter regexes (`pip install ".[re2]"`; falls back to stdlib `re`) |

Install all at once:
```bash
pip install "mcp[cli]>=1.8.0" lxml psutil
```

## Quick Start with Claude Code

The recommended way to use ProcmonMCP is via **stdio** transport with Claude Code. The server starts without any file loaded — you (or the LLM) can then use the `load_file` tool to open a Procmon capture.

### Option 1: Add via Claude Code CLI

```bash
# Add ProcmonMCP as a stdio server (user-wide)
claude mcp add procmon --scope user -- python -m procmon_mcp

# Or with a file pre-loaded at startup
claude mcp add procmon --scope user -- python -m procmon_mcp --input-file /path/to/capture.xml.gz

# Or scoped to the current project only
claude mcp add procmon --scope project -- python -m procmon_mcp
```

### Option 2: Add via JSON

```bash
claude mcp add-json procmon '{
  "type": "stdio",
  "command": "python",
  "args": ["-m", "procmon_mcp"]
}'
```

### Option 3: Edit configuration files directly

Claude Code reads MCP server configuration from these locations:

| Scope | File | Description |
|-------|------|-------------|
| Project (shared, version-controlled) | `.mcp.json` in project root | Shared with the team |
| Project (personal) | `.claude/settings.local.json` | Your local overrides |
| User (global) | `~/.claude.json` | Available across all projects |

Example `.mcp.json` for a shared project:

```json
{
  "mcpServers": {
    "procmon": {
      "type": "stdio",
      "command": "python",
      "args": ["-m", "procmon_mcp"]
    }
  }
}
```

Example with a pre-loaded file and options:

```json
{
  "mcpServers": {
    "procmon": {
      "type": "stdio",
      "command": "python",
      "args": [
        "-m", "procmon_mcp",
        "--input-file", "/path/to/capture.xml.gz",
        "--no-stack-traces"
      ]
    }
  }
}
```

### Option 4: Streamable HTTP transport

For network access or multi-client scenarios, use Streamable HTTP:

```bash
# Add as an HTTP server (start the server separately first)
claude mcp add --transport http procmon http://127.0.0.1:8081/mcp
```

Then start the server:
```bash
python -m procmon_mcp --transport streamable-http --mcp-port 8081
```

### Verify the connection

Once configured, verify that Claude Code can see ProcmonMCP:

```bash
claude mcp list
```

Inside a Claude Code session, you can also type `/mcp` to check the status of connected servers.

## Usage

### Typical workflow

1. **Start the server** (Claude Code does this automatically for stdio servers)
2. **Check status**: The LLM calls `get_status` to see if a file is loaded
3. **Load a file**: The LLM calls `load_file` with a path to a Procmon XML capture
4. **Analyse**: The LLM uses the analysis tools to investigate the log data

### Command-line arguments

| Argument | Default | Description |
|----------|---------|-------------|
| `--input-file ` | *(none)* | Pre-load a Procmon XML file at startup. If omitted, use `load_file` from the MCP client. |
| `--transport ` | `stdio` | Transport protocol: `stdio`, `streamable-http`, or `sse` (deprecated). |
| `--mcp-host ` | `127.0.0.1` | Host address (HTTP transports only). |
| `--mcp-port ` | `8081` | Port number (HTTP transports only). |
| `--no-stack-traces` | off | Skip loading stack traces to save memory. |
| `--no-extra-data` | off | Skip loading unknown/extra event fields to save memory. |
| `--no-cache` | off | Bypass the parsed-capture cache (always re-parse, and refresh the cache). |
| `--clear-cache` | off | Remove all cached parsed captures, then exit. |
| `--debug` | off | Enable verbose debug logging. |
| `--log-file ` | *(console)* | Write logs to a file instead of the console. |
| `--profile` | off | Enable cProfile profiling (for development). |

### Examples

**Start with stdio (no file pre-loaded — use `load_file` from the client):**
```bash
python -m procmon_mcp
```

**Pre-load a compressed XML file:**
```bash
python -m procmon_mcp --input-file /path/to/capture.xml.gz
```

**Start with Streamable HTTP on a custom port:**
```bash
python -m procmon_mcp --transport streamable-http --mcp-port 9000
```

**Skip stack traces for a very large file:**
```bash
python -m procmon_mcp --input-file /path/to/huge_capture.xml --no-stack-traces --no-extra-data
```

## Transport Protocols

| Transport | Use case | Status |
|-----------|----------|--------|
| **stdio** | Local use with Claude Code, Claude Desktop, etc. | **Recommended** |
| **streamable-http** | Network access, multiple clients, remote deployment | Supported |
| **sse** | Legacy MCP clients that do not yet support Streamable HTTP | **Deprecated** (MCP spec 2025-03-26) |

### stdio (recommended)

The simplest and most reliable transport. Claude Code spawns the server as a child process and communicates over stdin/stdout. No network configuration required.

### Streamable HTTP

Uses a single HTTP endpoint (`/mcp`) for all communication. Supports session management, optional SSE streaming for long-running operations, and is designed for scalability.

```bash
python -m procmon_mcp --transport streamable-http --mcp-host 0.0.0.0 --mcp-port 8081
```

The server will be available at `http://:/mcp`.

### SSE (deprecated)

> **Deprecated since MCP specification 2025-03-26.** SSE is retained for backwards compatibility but will be removed in a future release. Please migrate to `streamable-http` or `stdio`.

```bash
python -m procmon_mcp --transport sse --mcp-port 8081
```

## User Configuration

ProcmonMCP stores user preferences in `~/.procmonmcp/config.json`. This file is created automatically and remembers:

- The last loaded file path (shown as a hint in `get_status` when no file is loaded)
- Loading preferences (`no_stack_traces`, `no_extra_data`)

No API keys or authentication tokens are required — ProcmonMCP is a purely local analysis tool.

### Parsed-capture cache

Parsing a large capture is expensive (tens of seconds to minutes). After a successful
parse, ProcmonMCP serializes the optimised in-memory representation (events, interners,
indices, process tables) to `~/.procmonmcp/cache/`, keyed on the source file's path,
size, and modification time plus the load options. Reloading the same unchanged file is
then served from the cache and is near-instant — in practice a 20s parse drops to well
under a second.

- The cache is invalidated automatically when the file changes (mtime/size) or when the
  cache format version changes. Different `no_stack_traces`/`no_extra_data` options are
  cached separately.
- Bypass it with `--no-cache` (CLI) or `no_cache: true` (the `load_file` tool); the
  `from_cache` field in the load response indicates whether the cache was used.
- Clear it with `--clear-cache` (CLI) or the `clear_cache` tool. The cache is
  size-bounded with LRU eviction (default 5 GiB; override with the
  `PROCMONMCP_CACHE_MAX_BYTES` environment variable).
- **Security:** cache files are serialized with Python's `pickle` and are read back only
  from your user-owned `~/.procmonmcp/cache` directory (only this tool's own output is
  ever deserialized). Do not point the cache at a location other users can write to.

## Available MCP Tools

### Lifecycle Tools

| Tool | Description |
|------|-------------|
| `get_status()` | Returns the current server state — whether a file is loaded, loading progress, memory usage, and available actions. **Call this first.** |
| `load_file(file_path, no_stack_traces?, no_extra_data?, no_cache?)` | Loads a Procmon XML file (.xml, .gz, .bz2, .xz) for analysis. Uses the parsed-capture cache for near-instant reloads (`from_cache` in the response says whether it was used). Set `no_cache: true` to bypass the cache. Provides progress feedback. Replaces any previously loaded data. |
| `close_file()` | Closes (unloads) the currently loaded capture and frees its memory. Analysis tools are unavailable until another file is opened with `load_file`. Does not remove the on-disk cache. |
| `clear_cache()` | Removes all on-disk parsed-capture caches. Reclaims disk space and forces a clean re-parse on the next load. Does not affect currently loaded data. |

### Data Retrieval Tools

| Tool | Description |
|------|-------------|
| `get_loaded_file_summary()` | Returns a detailed summary of the loaded file — filename, counts, compression, index stats, interner stats, and selective loading flags. |
| `get_metadata()` | Returns basic metadata (filename, type, event/process counts). |
| `list_processes()` | Lists unique processes (PID, name, image path, parent PID) from the process list section. |
| `get_process_details(pid)` | Returns detailed properties for a specific process by PID. |
| `query_events(...)` | Queries events with flexible filters — by process, **PID** (`filter_pid`), operation, result, path (contains/regex), detail (regex), timestamp range, and stack module path. Returns event summaries with index. |
| `get_event_details(event_index)` | Returns all properties for a specific event by its index. |
| `get_event_stack_trace(event_index)` | Returns the call stack for a specific event (module path, location, address). |

### Analysis Tools

| Tool | Description |
|------|-------------|
| `count_events_by_process()` | Counts events per process name. |
| `summarize_operations_by_process(process_name_filter)` | Counts operations for a specific process. |
| `get_timing_statistics(group_by)` | Calculates duration statistics grouped by process or operation. |
| `get_process_lifetime(pid)` | Finds the Process Create and Process Exit timestamps for a given PID. |
| `find_file_access(path_contains, limit?)` | Finds file system events matching a path substring (case-insensitive). |
| `find_network_connections(process_name)` | Returns enriched records for the remote endpoints a process accessed: endpoint, host/ip/hostname/port, operations, inferred directions (connect/send/receive), results, event count, and first/last-seen timestamps — ranked by count. |
| `list_network_connections(limit?)` | Capture-wide network triage: one enriched record per (process, PID, endpoint) across all processes, ranked by event count. |
| `get_network_top_talkers(limit?)` | Ranks unique remote endpoints across the whole capture by event count, with the count of distinct processes (and their names) that touched each. |

### Export Tools

| Tool | Description |
|------|-------------|
| `export_query_results(...)` | Exports filtered events to CSV or JSON file. Uses the same filters as `query_events`. |

## MCP Clients

ProcmonMCP works with any MCP-compatible client. Below are setup instructions for popular clients.

### Claude Code (recommended)

See the [Quick Start with Claude Code](#quick-start-with-claude-code) section above.

### Claude Desktop

Add the following to your Claude Desktop configuration file:
- macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows: `%APPDATA%\Claude\claude_desktop_config.json`

```json
{
  "mcpServers": {
    "procmon": {
      "command": "python",
      "args": ["-m", "procmon_mcp"]
    }
  }
}
```

### Cline

For Cline with Streamable HTTP transport, first start the server:

```bash
python -m procmon_mcp --transport streamable-http --mcp-port 8081
```

Then in Cline, select MCP Servers and add:
- **Server Name:** ProcmonMCP
- **Server URL:** `http://127.0.0.1:8081/mcp`

## Example LLM Prompts for Malware Analysis

*(Assuming a Procmon XML file is loaded)*

### Initial Triage

- "Get the summary of the loaded file."
- "List the unique processes found in the log."
- "Count the events per process." *(Identify high-activity processes)*
- "Calculate timing statistics grouped by process." *(Identify long-duration events)*

### Investigating a Suspicious Process

- "Get details for process PID 4568." *(Check command line, parent PID, image path)*
- "Summarise operations for process `suspicious.exe`."
- "Query events where filter_process is `suspicious.exe` and filter_operation is `RegSetValue`, limit 10."
- "Find network connections for process `suspicious.exe`." *(Enriched: directions, results, counts, first/last-seen)*
- "List network connections across the whole capture." *(Capture-wide triage, busiest first)*
- "Show the network top talkers." *(Rank remote endpoints by event count)*
- "Find file access containing `temp\\suspicious_data`, limit 50."

### Looking for Persistence

- "Query events where filter_operation is `RegSetValue` and filter_path_contains is `CurrentVersion\\Run`, limit 20."
- "Query events where filter_operation is `CreateFile` and filter_path_contains is `StartUp`, limit 10."

### Troubleshooting Errors

- "Query events where filter_result is `ACCESS DENIED`, limit 10."
- "Query events where filter_result is `NAME NOT FOUND`, limit 10."
- "Get details for event 987."
- "Get stack trace for event 987."

### Exporting Data

- "Export query results to `suspicious_reg_writes.csv` where filter_process is `suspicious.exe` and filter_operation contains `RegSet`."
- "Export query results to `network_activity.json` in json format."

## Performance and Indexing

ProcmonMCP builds four indices during file loading for fast filtered lookups:

| Index | Used b

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [JameZUK](https://github.com/JameZUK)
- **Source:** [JameZUK/ProcmonMCP](https://github.com/JameZUK/ProcmonMCP)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-jamezuk-procmonmcp
- Seller: https://agentstack.voostack.com/s/jamezuk
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
