systeminternals-mcp (scaffold)
Minimal FastMCP-compatible scaffold that demonstrates dynamic registration and safe subprocess wrapping for exposing Sysinternals and NirSoft binaries.
Quick demo:
python server.py --demo procexp64
Start the MCP stdio server:
python server_mcp.py
Edit config.ini to adjust server settings (log level, timeout, allow_destructive).
The server no longer requires explicit binary paths — it scans the binaries/ directory recursively.
Security notes: This scaffold sanitizes arguments and uses asyncio.create_subprocess_exec without a shell. Extend with explicit safety filters before using in production.
Safety filter: destructive tools (for example sdelete, psexec, pskill) are blocked by default. To run them you must either:
- Add
--confirmto the tool arguments, or - Set
allow_destructive = truein the[server]section ofconfig.ini.
The server also scans a binaries directory recursively if present; place your tool folders (e.g., systeminternals, nirsoft) under binaries.
Setup
Prerequisites:
- Python 3.11+ (recommended) and
venv.
Quick setup:
python -m venv .venv
.\.venv\Scripts\activate
pip install --upgrade pip
pip install -r requirements.txt
Running
- Run a single-tool demo (CLI):
python server.py --demo pslist64
- Start the long-running MCP stdio server (for agent integration):
python server_mcp.py
The --demo mode is useful for simple CLI usage and for coding agents that can execute shell commands and parse JSON output. server_mcp.py exposes the full MCP stdio endpoint for clients that implement the MCP protocol.
Using from a CLI or a coding agent
- Simple CLI / scripting approach (recommended for automation and agents that can run subprocesses): the
--democommand prints JSON to stdout which is easy to parse from any language.
Example Python snippet (agent or script):
import subprocess, json
proc = subprocess.run([
'python', 'server.py', '--demo', 'pslist64', '--',
# additional tool args go here as separate items
], capture_output=True, text=True)
if proc.returncode == 0 and proc.stdout:
result = json.loads(proc.stdout)
print(result)
else:
print('error', proc.stderr)
Note: place any tool arguments after --demo <toolname>; the demo command will join remaining argv pieces for the tool.
- Long-running MCP server (for advanced agents):
- Start the server with
python server_mcp.py(it will register tools frombinaries.jsonor thebinaries/directory). - Use an MCP-capable client to connect over stdio (spawn the server as a child process and implement the MCP framing). Many agent frameworks support providing a long-lived process that the agent can call into; in that case the MCP stdio server gives a stable RPC surface.
If your agent framework doesn't implement MCP natively, use the simple subprocess approach above to execute server.py --demo per-request.
Security and best practices
- Never allow untrusted agents or users to run destructive tools. Destructive tools are blocked by default; confirmations are required (interactive prompt,
--confirmorallow_destructive=trueinconfig.ini). - When generating per-tool schemas or probing help text, run the probe in an isolated environment (VM or disposable container) to avoid accidental execution of unsafe binaries.
- For production use, add authentication around the MCP stdio process and run under restricted privileges.
CI
A GitHub Actions workflow is included at .github/workflows/ci.yml that runs the test suite on push and pull requests.
mcpServers (IDE / agent integration)
If your editor/agent supports a mcpServers config (for example the Gemini client settings), add entries that either start the stdio MCP server or point to a running HTTP MCP endpoint.
Example — start the long-lived stdio MCP server from this repo (preferred for full MCP integration):
"systeminternals-mcp": {
"command": "python",
"args": [
"C:\\path\\to\\the\\server_mcp.py"
]
}
Example — demo/one-shot entry that runs --demo and prints JSON (useful for simple agents that call subprocesses):
"systeminternals-mcp-demo": {
"command": "python",
"args": [
"C:\\path\\to\\the\\server.py",
"--demo"
]
}
Example — point to an existing HTTP MCP endpoint:
"systeminternals-mcp-http": {
"url": "http://127.0.0.1:12345/mcp"
}
Notes:
- Use absolute Windows paths (escape backslashes in JSON) or a plain
pythoncommand if the environment activates the virtualenv automatically. - If your client supports
cwdandenv, set them so the server runs in the repo root and uses the.venvPython. - Prefer the stdio MCP server (
server_mcp.py) for integrated agents; use--demofor simple per-request subprocess calls that return JSON.
