systeminformer-mcp
by inflearner0
README.md
# systeminformer-mcp
An MCP server that exposes [System Informer](https://github.com/winsiderss/systeminformer)'s
capabilities as tools: processes, threads, modules, handles, memory, services,
network endpoints, drivers, windows and file signatures — plus process launching
and control.
54 tools, verified end-to-end on Windows 11 (build 26200).
## How it works
Modern System Informer builds have **no headless command mode** — the old
`-ctype` / `-cobject` / `-caction` switches were removed, and the remaining
command line switches only configure the GUI. Scraping a GUI would be both
fragile and lossy.
So this server does what System Informer itself does: it calls the same native
NT APIs directly (`NtQuerySystemInformation`, `NtQueryInformationProcess`,
`NtDuplicateObject`, the SCM APIs, `iphlpapi`, `WinVerifyTrust`, …) through
`ctypes`. Results come back as structured JSON rather than table rows.
The installed System Informer application is still used for two things:
- **GUI hand-off** — `launch_systeminformer_gui`, `launch_peview` for the live
graphs and interactive views that do not translate to tool output.
- **`dbghelp.dll`** — the copy shipped with System Informer writes process dumps.
Neither is required. If System Informer is not installed, every inspection and
control tool still works; only those two hand-off tools become unavailable.
## Install
```bash
pip install mcp
```
Then register the server with your MCP client. For Claude Code — note the
`PYTHONPATH`, which is what lets `python -m si_mcp` find the package from any
working directory:
```bash
claude mcp add systeminformer --scope user -e PYTHONIOENCODING=utf-8 -e "PYTHONPATH=C:\path\to\systeminformer-mcp" -- python -m si_mcp
```
Or add it to your client's config file directly:
```json
{
"mcpServers": {
"systeminformer": {
"command": "python",
"args": ["-m", "si_mcp"],
"env": {
"PYTHONIOENCODING": "utf-8",
"PYTHONPATH": "C:\\path\\to\\systeminformer-mcp"
}
}
}
}
```
Alternatively `pip install -e .` from the project root, which puts a
`systeminformer-mcp` console script on PATH and makes `PYTHONPATH` unnecessary.
Set `SYSTEMINFORMER_PATH` if System Informer is installed somewhere other than
`C:\Program Files\SystemInformer`.
## Privileges
Windows, not this server, decides what is visible. Run the server **elevated**
for full coverage — call `server_status` at any time to see exactly what is and
is not available:
| Running as | What you get |
|---|---|
| Standard user | Your own processes in full; other users' processes are limited |
| Elevated | Nearly everything: all processes, kernel addresses, service control |
| Elevated + KSystemInformer driver | Protected processes (PPL, antimalware) too |
Unelevated, Windows withholds kernel addresses (driver base addresses read back
as `0x0`) and thread start addresses for processes you do not own. The server
works around the latter by re-querying through a thread handle where it can.
## Tools
**System** — `system_overview`, `system_cpu_usage`, `system_memory`, `system_uptime`
**Processes** — `list_processes`, `process_tree`, `process_details`,
`process_token`, `process_modules`, `process_threads`, `thread_details`
**Process control** — `launch_process`, `launch_process_elevated`,
`terminate_process`, `terminate_process_tree`, `suspend_process`,
`resume_process`, `set_process_priority`, `set_process_affinity`,
`set_process_critical`, `empty_working_set`, `create_process_dump`
**Threads** — `suspend_thread`, `resume_thread`, `terminate_thread`,
`set_thread_priority`, `set_thread_affinity`
**Memory** — `process_memory_regions`, `process_memory_summary`,
`read_process_memory`, `write_process_memory`, `protect_process_memory`,
`search_process_memory`, `process_memory_strings`
**Handles** — `list_handles`, `handle_type_summary`, `find_handles_by_name`,
`close_handle`
**Services** — `list_services`, `service_details`, `control_service`,
`set_service_start_type`, `create_service`, `delete_service`
**Network** — `network_connections`, `port_owner`
**Drivers & windows** — `list_drivers`, `list_windows`, `window_action`
**Files** — `file_details`, `verify_file_signature`
**System Informer** — `server_status`, `launch_systeminformer_gui`, `launch_peview`
### Examples
```
"What's using port 3000?" -> port_owner
"Which process has this DLL locked?" -> find_handles_by_name
"Why is my machine at 100% CPU?" -> list_processes sort_by=cpu
"Start notepad minimized, then suspend it" -> launch_process, suspend_process
"Is this binary signed?" -> verify_file_signature
```
## Safety
Tools that cannot be undone, or that can destabilise a running process, require
an explicit `confirm=true`:
- `write_process_memory` — can corrupt or crash the target
- `close_handle` — the owning process is not told its handle vanished
- `terminate_process_tree` — kills every descendant
- `delete_service` — service registration cannot be restored by this server
- `set_process_critical` — **terminating a critical process bugchecks Windows**
`launch_process_elevated` routes through the standard Windows UAC consent
prompt. This server never accepts, stores or transmits credentials; to run a
process as a *different* user, use the System Informer GUI's Run As dialog.
## Notes on correctness
A few details that are easy to get wrong and are handled here:
- **Object names can hang.** Naming a handle means duplicating it and calling
`NtQueryObject`, which blocks forever on a synchronous named pipe whose peer
never answers. Like System Informer, this runs on a worker thread with a
timeout; a wedged worker is retired rather than reused, and the handle is
deliberately leaked instead of being closed out from under the blocked call.
- **Process names are not NUL-terminated.** `SYSTEM_PROCESS_INFORMATION`
carries an explicit `Length`; decoding by scanning for a terminator reads
past the string into adjacent data and yields unpaired UTF-16 surrogates.
All tool output is additionally sanitized so no malformed name from another
process can fail a response.
- **Token structures embed pointers into their own buffer.** `TOKEN_USER` and
friends must be read from a live allocation, not a copied `bytes`.
- **Fixed-size info classes reject over-sized buffers.** `SystemBasicInformation`
and the per-processor tables want exactly the size the running kernel expects,
which differs across Windows versions, so the size is queried first.
- **PID reuse breaks process trees.** A "parent" created after its child is
treated as recycled, and the child is reported at the root.
## Tests
```bash
python tests/test_e2e.py
```
Starts the server over real MCP stdio transport, calls a tool from every group,
and round-trips a live process: launch → inspect → suspend → resume → dump →
terminate. It also asserts that each guarded tool refuses to act without
`confirm=true`. 44 checks.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues