Skip to content

JameZUK/ProcmonMCP

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

49 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ProcmonMCP

ProcmonMCP is a Model Context Protocol (MCP) 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
  • 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.

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

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

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

Install all at once:

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

# 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

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:

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

Example with a pre-loaded file and options:

{
  "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:

# 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:

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

Verify the connection

Once configured, verify that Claude Code can see ProcmonMCP:

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 <path> (none) Pre-load a Procmon XML file at startup. If omitted, use load_file from the MCP client.
--transport <mode> stdio Transport protocol: stdio, streamable-http, or sse (deprecated).
--mcp-host <ip> 127.0.0.1 Host address (HTTP transports only).
--mcp-port <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.
--debug off Enable verbose debug logging.
--log-file <path> (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):

python -m procmon_mcp

Pre-load a compressed XML file:

python -m procmon_mcp --input-file /path/to/capture.xml.gz

Start with Streamable HTTP on a custom port:

python -m procmon_mcp --transport streamable-http --mcp-port 9000

Skip stack traces for a very large file:

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.

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

The server will be available at http://<host>:<port>/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.

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.

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?) Loads a Procmon XML file (.xml, .gz, .bz2, .xz) for analysis. Provides progress feedback. Replaces any previously 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, 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) Finds unique remote network endpoints accessed by a process.

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 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
{
  "mcpServers": {
    "procmon": {
      "command": "python",
      "args": ["-m", "procmon_mcp"]
    }
  }
}

Cline

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

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."
  • "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 by Complexity
Process name (interned ID) query_events, count_events_by_process O(1) lookup
Operation (interned ID) query_events, summarize_operations_by_process O(1) lookup
PID get_process_lifetime O(1) lookup with set intersection
File path (interned ID) find_file_access O(unique_paths) substring scan

For filters not backed by an index (e.g., regex, path contains, stack module path), ProcmonMCP falls back to a linear scan of all events. Use indexed filters first to narrow results, then apply more expensive filters.

Limitations

  • Memory usage: Whilst optimised with string interning, loading extremely large XML files (millions of events with stack traces) can consume significant RAM. Use --no-stack-traces and --no-extra-data for very large files.
  • Loading time: Parsing and optimising large XML files takes time, particularly compressed ones. Progress is reported during loading.
  • XML structure: Relies on the standard Procmon XML export structure. Malformed or non-standard XML will likely cause parsing errors.
  • Stack traces: Stack trace quality depends on what Procmon resolved and included in the XML export. Requires running Procmon with symbols configured correctly.
  • Single file at a time: Only one file can be loaded at any given time. Loading a new file replaces the previous data.

Contributing

Contributions are welcome! Please feel free to submit pull requests or open issues on GitHub.

About

An MCP server for procmon files

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages