Forensic Artifact Investigator
FreeNot checkedMCP server for read-only forensic analysis of evidence files using local utilities (file, ExifTool, strings, Volatility).
About
MCP server for read-only forensic analysis of evidence files using local utilities (file, ExifTool, strings, Volatility).
README
forensic-analyzer-mcp is a production-oriented Model Context Protocol (MCP) server for bounded, read-only inspection of forensic evidence files. It is built with NitroStack and calls real local forensic utilities—file, ExifTool, GNU strings, and Volatility—through literal argument-array subprocesses. It does not invent or simulate forensic output.
The GitHub repository is named forensic-analyzer-mcp. The MCP server identifier remains forensic-artifact-investigator, which is the name a client may display during discovery.
Important: this is analyst-support software, not a malware verdict engine or a legal conclusion engine. An extension/MIME mismatch, a URL, a
malfindresult, or a VirusTotal count is evidence for review—not proof of maliciousness or innocence.
Contents
- What it does
- Architecture
- MCP capabilities
- Output and interpretation
- Platform support
- Linux setup
- Windows setup
- Docker setup
- Connect Codex, Claude Code, or another MCP client
- Use the server
- Configuration
- Testing and verification
- Security and operational limits
- Troubleshooting
What it does
The server exposes three tools:
extract-metadatavalidates an evidence path, detects MIME type withfile, reads metadata with ExifTool, calculates SHA-256, and compares the extension against a bundled expected-MIME reference table.extract-stringsruns realstrings -n 6, returns bounded output, and labels matching IP addresses, URLs/domains, and suspicious keywords as indicators.analyze-memory-dumpruns Volatility 3 (preferred) or Volatility 2 against a Windows memory dump and reports each plugin independently assuccess,failed, orunavailable.
Every tool attempts exactly one serialized append to a local JSONL chain-of-custody log. The only optional network operation is a hash-only VirusTotal lookup; evidence bytes are never uploaded.
It intentionally does not perform YARA scanning, registry analysis, malware execution, uploading, deletion, sandboxing, or automatic severity scoring.
Architecture
flowchart LR
C["MCP client: Codex, Claude Code, or another harness"] --> S["NitroStack server over stdio"]
S --> A["analyze module"]
S --> M["memory module"]
A --> P["Canonical evidence-path validation"]
A --> F["file + ExifTool + GNU strings"]
A --> H["Streaming SHA-256"]
A --> L["Append-only JSONL analysis log"]
A --> T["Optional hash-only VirusTotal lookup"]
M --> P
M --> V["Volatility 3 or explicit Volatility 2 fallback"]
M --> L
W["analysis-report widget artifact"] --> C
How a request flows
- The MCP client sends a tool request over stdio.
- The server resolves
EVIDENCE_ROOTand the requested path withrealpath, rejects traversal/symlink escapes/non-regular files, and only permits files inside that root. - It invokes a configured forensic binary with
spawn(binary, args, { shell: false }). - Command stdout/stderr, runtime, and return payloads are bounded. Timeouts and output caps are explicitly reported.
- The structured result and a brief factual log record are returned to the client.
NitroStack supplies MCP registration, schema validation, stdio transport, and widget compilation. The bootstrap intentionally uses createServer() rather than NitroStack's starter factory because that factory adds a health resource and would violate the deliberately minimal resource inventory below.
MCP capabilities
| Kind | Identity | Purpose |
|---|---|---|
| Tool | extract-metadata |
File type, Exif metadata, SHA-256, extension/MIME comparison |
| Tool | extract-strings |
Bounded strings -n 6 extraction and indicator scan |
| Tool | analyze-memory-dump |
Real Volatility analysis with independent plugin status |
| Resource | signatures://magic-bytes |
Bundled extension-to-expected-MIME reference table |
| Resource | case://analysis-log |
Read-only recent view of the local append-only JSONL log |
| Resource template | signatures://threat-intel/{hash} |
Hash-only reputation lookup; listed as signatures://threat-intel |
| Prompt | full-file-analysis |
A safe, ordered analysis workflow prompt |
| Widget artifact | analysis-report |
Static NitroStack display artifact for supported clients |
There are exactly two feature modules: analyze and memory. A fully native interactive MCP App widget must register a ui:// resource. To preserve the literal three-resource protocol surface, this repository compiles the analysis-report artifact without registering an extra UI resource. Some MCP clients will expose the tools/resources/prompts but not render the widget; that is expected.
Output and interpretation
All tool outputs are structured JSON. Paths, hashes, timestamps, byte counts, and forensic results vary by evidence and host. The following are shortened, sanitized examples of the shapes clients receive.
extract-metadata
Request:
{ "filePath": "/evidence/suspect_photo.jpg" }
Representative success response:
{
"tool": "extract-metadata",
"success": true,
"targetFile": "/evidence/suspect_photo.jpg",
"fileSizeBytes": 18342,
"extension": ".jpg",
"detectedMimeType": "image/jpeg",
"expectedMimeTypes": ["image/jpeg"],
"extensionKnown": true,
"extensionMismatch": false,
"mismatchReason": null,
"mismatchCheckStatus": "checked",
"sha256": "<64-character SHA-256>",
"hashAlgorithm": "sha256",
"metadata": {
"camera": { "make": null, "model": null, "lens": null },
"gps": { "latitude": null, "longitude": null, "altitude": null },
"software": null,
"timestamps": {
"createDate": null,
"dateTimeOriginal": null,
"modifyDate": null
},
"dimensions": { "width": 640, "height": 480 }
},
"filesystem": {
"mode": 33188,
"modifiedAt": "2026-07-13T00:00:00.000Z",
"changedAt": "2026-07-13T00:00:00.000Z",
"birthtime": "2026-07-13T00:00:00.000Z"
},
"execution": {
"fileCommand": { "success": true, "durationMs": 8, "exitCode": 0, "signal": null, "timedOut": false, "truncated": false, "capturedBytes": 11 },
"exiftoolCommand": { "success": true, "durationMs": 42, "exitCode": 0, "signal": null, "timedOut": false, "truncated": false, "capturedBytes": 572 }
}
}
extensionMismatch: true means the file utility detected a MIME type outside the expected list for the observed extension. It is a confirmed file-type discrepancy, not a malware verdict. The bundled table is a comparison reference; real MIME detection comes from the operating system's file executable.
extract-strings
Request:
{ "filePath": "/evidence/suspect.bin" }
Representative response for a file containing indicators:
{
"tool": "extract-strings",
"success": true,
"targetFile": "/evidence/suspect.bin",
"totalCapturedStringLines": 132,
"returnedStringCount": 132,
"returnedStringLines": ["...", "https://example.invalid/loader", "powershell -EncodedCommand ..."],
"resultsTruncated": false,
"truncationReason": null,
"truncationReasons": [],
"patternMatches": {
"ipAddresses": [{ "value": "198.51.100.42", "normalizedValue": "198.51.100.42", "sourceString": "connect 198.51.100.42" }],
"urlsAndDomains": [{ "value": "https://example.invalid/loader", "normalizedValue": "https://example.invalid/loader", "sourceString": "https://example.invalid/loader" }],
"suspiciousKeywords": [{ "keyword": "powershell", "sourceString": "powershell -EncodedCommand ..." }]
},
"patternMatchesTruncated": false,
"execution": {
"stringsCommand": { "success": true, "durationMs": 11, "exitCode": 0, "signal": null, "timedOut": false, "truncated": false, "capturedBytes": 4521 }
}
}
When resultsTruncated is true, the response is deliberately partial. Read truncationReasons before drawing conclusions; the complete tool output was not retained in MCP memory.
analyze-memory-dump
Request:
{ "filePath": "/evidence/windows-memory.raw" }
Representative partial/failure response:
{
"tool": "analyze-memory-dump",
"targetFile": "/evidence/windows-memory.raw",
"success": false,
"volatilityVersion": 3,
"selectedProfile": null,
"processList": [],
"networkConnections": [],
"flaggedInjectedRegions": [],
"pluginResults": {
"info": { "status": "failed", "parsed": false, "error": "Volatility plugin exited with code 1.", "rawOutputExcerpt": "..." },
"pslist": { "status": "failed", "parsed": false, "error": "Volatility plugin exited with code 1.", "rawOutputExcerpt": "..." },
"netscan": { "status": "unavailable", "parsed": false, "error": "A compatible dump or symbols are required.", "rawOutputExcerpt": "" },
"malfind": { "status": "unavailable", "parsed": false, "error": "A compatible dump or symbols are required.", "rawOutputExcerpt": "" }
}
}
success: false does not mean the dump is clean. It means no Volatility plugin completed successfully. Likewise, a successful malfind plugin with zero rows only reports that plugin's returned data; it is not a blanket clean verdict.
Resources
signatures://magic-bytesreturns the bundled expected-MIME mapping used by the extension comparison.case://analysis-logreturns bounded recent JSONL pluslineCount,truncated, andomittedBytes. It never returns full raw strings/Volatility output.signatures://threat-intel/<md5-or-sha1-or-sha256>returns a small reputation object. The deterministic EICAR fixture can be checked without a key or network access:
{
"status": "found",
"source": "deterministic-eicar-fixture",
"hash": "44d88612fea8a8f36de82e1278abb02f",
"hashAlgorithm": "md5",
"malicious": 1,
"suspicious": 0,
"harmless": 0,
"undetected": 0,
"timeout": 0,
"failure": 0,
"summary": "Known EICAR antivirus test-file hash; deterministic test response."
}
For any other valid hash with no API key configured, the resource returns:
{
"status": "not configured",
"message": "Set VIRUSTOTAL_API_KEY to enable live threat intelligence lookups."
}
An unknown VirusTotal hash is not proof that the evidence is safe. Only a hash—not the evidence file—is sent to VirusTotal when a key is configured.
Platform support
| Platform | Status | Notes |
|---|---|---|
| Linux native | Supported | Primary development/runtime path. The setup script supports apt, dnf, yum, and apk. |
| Linux Docker | Supported configuration | Debian/Node 24 image packages the required tools; use a persistent log mount. |
| Windows + WSL2 | Recommended | Run the Linux instructions inside Ubuntu or another WSL distribution. |
| Windows + Docker Desktop | Recommended | Run the Linux container from PowerShell and mount evidence read-only. |
| Native Windows | Best effort | Provide compatible file, ExifTool, GNU strings, and Volatility executables explicitly. |
| macOS | Development best effort | Not the target deployment; set paths to GNU-compatible binaries explicitly. |
The CI workflow runs the portable test/build/stdio-verification path on Ubuntu. A real Windows memory image is not bundled, so successful Volatility analysis must be validated against an authorized, compatible dump in your own environment.
Linux setup
1. Clone and install
git clone https://github.com/guyoverclocked/forensic-analyzer-mcp.git
cd forensic-analyzer-mcp
# Installs Linux dependencies and Volatility 3. A project-local evidence
# directory avoids requiring a writable /evidence directory on the host.
EVIDENCE_ROOT="$PWD/evidence" bash scripts/setup-environment.sh
npm ci
npm --prefix src/widgets ci
mkdir -p evidence forensic-logs
cp .env.example .env
The Bash setup helper installs or verifies Node.js 20+, file, ExifTool, GNU binutils (strings), Python, and Volatility 3. It prints verified executable paths at the end. It does not write secrets or overwrite an existing .env.
2. Configure the server
Edit .env and replace every path with an absolute path from your machine. For a Volatility venv created by the helper, a typical native Linux configuration is:
EVIDENCE_ROOT=/absolute/path/to/forensic-analyzer-mcp/evidence
ANALYSIS_LOG_PATH=/absolute/path/to/forensic-analyzer-mcp/forensic-logs/analysis-log.jsonl
FILE_BINARY=/usr/bin/file
EXIFTOOL_BINARY=/usr/bin/exiftool
STRINGS_BINARY=/usr/bin/strings
VOLATILITY_MAJOR_VERSION=3
VOLATILITY_BINARY=/absolute/path/to/forensic-analyzer-mcp/.venv-volatility/bin/vol
MCP_TRANSPORT_TYPE=stdio
Some Volatility installations create vol3 rather than vol; use the actual path printed by scripts/setup-environment.sh. Put only authorized evidence inside EVIDENCE_ROOT. Do not commit that directory or the log to Git.
3. Build and verify
npm run lint
npm run typecheck
npm test
npm run build
EVIDENCE_ROOT="$PWD/tests/fixtures" \
EVIDENCE_TEST_PATH="$PWD/tests/fixtures/suspect_photo.jpg" \
npm run verify:mcp
npm run verify:mcp starts the built server as a real stdio MCP child process, confirms the exact tool/resource/prompt inventory, reads the EICAR fixture, and—when EVIDENCE_TEST_PATH is set—exercises metadata and strings extraction against the harmless tracked JPEG fixture.
4. Start through an MCP client
The production process is a stdio server, not an HTTP daemon:
npm run start:prod
Running it directly will appear to wait without printing a prompt. That is normal: it is waiting for JSON-RPC messages on standard input. Launch it through Codex, Claude Code, another MCP client, or the verifier rather than typing shell commands into it.
Windows setup
Recommended: WSL2
In an elevated PowerShell window, install WSL if needed:
wsl --install -d Ubuntu
Restart when Windows asks, open Ubuntu, and follow the Linux setup. Keep the repository under your WSL home directory for best filesystem performance. Evidence stored on Windows can be mounted through paths such as /mnt/c/Forensics/Case-001/evidence:
export EVIDENCE_ROOT=/mnt/c/Forensics/Case-001/evidence
bash scripts/setup-environment.sh
Then set the same WSL path in .env and in the MCP client configuration that runs inside WSL.
Native Windows (best effort)
The supplied setup script is Bash/Linux-only. Native Windows can work only if you install and point the server at compatible executables. Use Node.js 20+, ExifTool for Windows, a compatible file.exe, GNU strings.exe that supports -n 6, and Volatility.
In PowerShell, install dependencies and set absolute executable paths before building:
git clone https://github.com/guyoverclocked/forensic-analyzer-mcp.git
Set-Location forensic-analyzer-mcp
npm ci
npm --prefix src/widgets ci
$env:EVIDENCE_ROOT = "C:\Forensics\Case-001\evidence"
$env:ANALYSIS_LOG_PATH = "$PWD\forensic-logs\analysis-log.jsonl"
$env:FILE_BINARY = "C:\Tools\file\file.exe"
$env:EXIFTOOL_BINARY = "C:\Tools\exiftool\exiftool.exe"
$env:STRINGS_BINARY = "C:\Tools\binutils\strings.exe"
$env:VOLATILITY_MAJOR_VERSION = "3"
$env:VOLATILITY_BINARY = "C:\Tools\volatility\vol.exe"
$env:MCP_TRANSPORT_TYPE = "stdio"
npm run build
node .\dist\index.js
If any command is unavailable or incompatible, use WSL2 or Docker Desktop instead. Do not treat a missing tool's failure as a clean analysis result.
Docker setup
Docker provides a Linux runtime containing file, ExifTool, GNU strings, Python, and Volatility 3 at /opt/volatility/bin/vol.
Linux/macOS shell
docker build -t forensic-analyzer-mcp .
mkdir -p evidence forensic-logs
docker run --rm -i \
-v "$PWD/evidence:/evidence:ro" \
-v "$PWD/forensic-logs:/app/data" \
forensic-analyzer-mcp
The evidence mount is deliberately read-only. The second mount persists the append-only log because --rm deletes the container filesystem on exit. As with native stdio, a bare docker run -i appears to wait because it is waiting for MCP messages; configure the same command as an MCP server in a client.
Windows PowerShell / Docker Desktop
docker build -t forensic-analyzer-mcp .
New-Item -ItemType Directory -Force evidence, forensic-logs
docker run --rm -i -v "${PWD}\evidence:/evidence:ro" -v "${PWD}\forensic-logs:/app/data" forensic-analyzer-mcp
For Docker configuration, the image already has these values:
EVIDENCE_ROOT=/evidence
FILE_BINARY=/usr/bin/file
EXIFTOOL_BINARY=/usr/bin/exiftool
STRINGS_BINARY=/usr/bin/strings
VOLATILITY_BINARY=/opt/volatility/bin/vol
VOLATILITY_MAJOR_VERSION=3
MCP_TRANSPORT_TYPE=stdio
Connect Codex, Claude Code, or another MCP client
Build first with npm run build. For safety and portability, pass absolute EVIDENCE_ROOT and ANALYSIS_LOG_PATH values through the MCP client. Do not rely on .env when the client may launch the process from another working directory.
Codex
Codex supports local stdio MCP servers in ~/.codex/config.toml; a trusted project can instead use .codex/config.toml. Add the following to your local configuration, replacing each placeholder with an absolute path:
[mcp_servers.forensic-analyzer]
command = "node"
args = ["/absolute/path/to/forensic-analyzer-mcp/dist/index.js"]
cwd = "/absolute/path/to/forensic-analyzer-mcp"
startup_timeout_sec = 30
tool_timeout_sec = 360
default_tools_approval_mode = "prompt"
# Optional: only forward this if a VirusTotal lookup is authorized.
env_vars = ["VIRUSTOTAL_API_KEY"]
[mcp_servers.forensic-analyzer.env]
EVIDENCE_ROOT = "/absolute/path/to/authorized-evidence"
ANALYSIS_LOG_PATH = "/absolute/path/to/forensic-logs/analysis-log.jsonl"
FILE_BINARY = "/usr/bin/file"
EXIFTOOL_BINARY = "/usr/bin/exiftool"
STRINGS_BINARY = "/usr/bin/strings"
VOLATILITY_MAJOR_VERSION = "3"
VOLATILITY_BINARY = "/absolute/path/to/forensic-analyzer-mcp/.venv-volatility/bin/vol"
MCP_TRANSPORT_TYPE = "stdio"
Restart Codex, then use /mcp to confirm that forensic-analyzer is connected. The official Codex MCP documentation documents the [mcp_servers.<server-name>] table and its command, args, cwd, env, and env_vars fields.
For a Docker-backed Codex server, replace command and args with a docker run --rm -i command and mount the host evidence directory read-only. Keep the host log mount writable and never include secrets in a repository-scoped configuration file.
Claude Code
Use a user-scoped local stdio configuration so host paths and any credentials remain private. Replace the paths below:
claude mcp add \
--scope user \
--transport stdio \
--env EVIDENCE_ROOT=/absolute/path/to/authorized-evidence \
--env ANALYSIS_LOG_PATH=/absolute/path/to/forensic-logs/analysis-log.jsonl \
--env FILE_BINARY=/usr/bin/file \
--env EXIFTOOL_BINARY=/usr/bin/exiftool \
--env STRINGS_BINARY=/usr/bin/strings \
--env VOLATILITY_MAJOR_VERSION=3 \
--env VOLATILITY_BINARY=/absolute/path/to/forensic-analyzer-mcp/.venv-volatility/bin/vol \
--env MCP_TRANSPORT_TYPE=stdio \
forensic-analyzer \
-- node /absolute/path/to/forensic-analyzer-mcp/dist/index.js
Verify it with:
claude mcp list
claude mcp get forensic-analyzer
Inside Claude Code, use /mcp to inspect connection status, then invoke a tool. The Claude Code MCP guide documents claude mcp add, scopes, --env, and the required -- separator before the server command. On native Windows, use the full node.exe path if node is not discoverable by Claude Code.
Generic stdio MCP configuration
Many harnesses accept a JSON object in this shape (the enclosing key/name differs by client):
{
"mcpServers": {
"forensic-analyzer": {
"command": "node",
"args": ["/absolute/path/to/forensic-analyzer-mcp/dist/index.js"],
"cwd": "/absolute/path/to/forensic-analyzer-mcp",
"env": {
"EVIDENCE_ROOT": "/absolute/path/to/authorized-evidence",
"ANALYSIS_LOG_PATH": "/absolute/path/to/forensic-logs/analysis-log.jsonl",
"FILE_BINARY": "/usr/bin/file",
"EXIFTOOL_BINARY": "/usr/bin/exiftool",
"STRINGS_BINARY": "/usr/bin/strings",
"VOLATILITY_MAJOR_VERSION": "3",
"VOLATILITY_BINARY": "/absolute/path/to/forensic-analyzer-mcp/.venv-volatility/bin/vol",
"MCP_TRANSPORT_TYPE": "stdio"
}
}
}
}
Some clients require "type": "stdio"; add it if their schema asks for a transport type. Restart or reload the client after saving configuration. Never place VIRUSTOTAL_API_KEY or evidence paths in a shared/committed config file.
Use the server
Once discovery succeeds, an analyst can perform an ordered review:
- Call
extract-metadatafor an authorized file. - Call
extract-stringson the same file. - Read
signatures://threat-intel/<sha256-from-metadata>if a policy-approved hash lookup is needed. - Read
case://analysis-logto verify the local chronology. - For a legitimate Windows dump, call
analyze-memory-dumpand inspect every item inpluginResults.
The full-file-analysis prompt encodes this workflow. Invoke it with filePath and evidenceType (file, image, or memory_dump); it requests a report with the headings Confirmed Anomalies, Possible Anomalies, and Clean in that order.
Example analyst prompt for any MCP-aware harness:
Use full-file-analysis for /evidence/suspect_photo.jpg as an image. Show the
raw tool conclusions, distinguish a confirmed file-type discrepancy from
possible indicators, and state any incomplete/failed analysis explicitly.
Configuration
.env.example lists safe defaults. The process loads .env only relative to its current working directory, so MCP client configuration should still supply absolute paths explicitly.
| Variable | Meaning | Default |
|---|---|---|
EVIDENCE_ROOT |
Canonical directory from which evidence can be read | /evidence |
ANALYSIS_LOG_PATH |
Append-only JSONL chain-of-custody log destination | data/analysis-log.jsonl under process cwd |
FILE_BINARY |
file executable path/name |
file |
EXIFTOOL_BINARY |
ExifTool executable path/name | exiftool |
STRINGS_BINARY |
GNU-compatible strings executable path/name |
strings |
VOLATILITY_MAJOR_VERSION |
3 (preferred) or explicit 2 mode |
3 |
VOLATILITY_BINARY |
Verified Volatility executable path | unset; memory tool returns a dependency error |
VIRUSTOTAL_API_KEY |
Optional key for hash-only reputation lookups | unset; no network lookup |
FILE_COMMAND_TIMEOUT_MS |
Timeout for file, ExifTool, and strings |
60000 |
VOLATILITY_TIMEOUT_MS |
Timeout per Volatility plugin | 300000 |
MAX_RETURNED_STRINGS |
Maximum strings retained in MCP response | 5000 |
MAX_STRING_OUTPUT_BYTES |
Captured strings stdout cap | 2000000 |
VOLATILITY_MAX_OUTPUT_BYTES |
Captured Volatility stdout cap | 5000000 |
MAX_SUBPROCESS_STDOUT_BYTES, MAX_SUBPROCESS_STDERR_BYTES |
General command capture caps | 2000000, 512000 |
MCP_TRANSPORT_TYPE |
MCP transport selection | stdio |
Volatility 3 is the intended mode. It runs windows.info, windows.pslist, windows.netscan, and windows.malfind sequentially using JSON output where supported. Volatility 2 is only selected when explicitly configured: it first runs imageinfo, uses the first clearly suggested profile, and marks Windows plugins unavailable if no profile can be selected.
Testing and verification
Run these before publishing changes:
npm run lint
npm run typecheck
npm test
npm run build
npm run verify:mcp
Expected successful outcomes:
| Command | What it verifies |
|---|---|
npm run lint |
ESLint has no warnings/errors in source and tests |
npm run typecheck |
TypeScript compiles without emitting files |
npm test |
Unit tests plus real-command integration tests when compatible binaries are available |
npm run build |
NitroStack server and analysis-report widget artifact build |
npm run verify:mcp |
Real stdio discovery, exact capability inventory, EICAR resource, prompt, and optional fixture tool calls |
The integration test skips cleanly when its configured external forensic binaries are not available. A skip means that real-binary path was not exercised in that environment; it is not a successful forensic test. On Linux CI, the required packages are installed before the suite runs.
Security and operational limits
Read SECURITY.md before deploying against real evidence. In summary:
- Every evidence path is canonicalized and confined to
EVIDENCE_ROOT. Traversal, symlink escapes, directories, special files, and unreadable paths are rejected before a forensic subprocess runs. - Subprocesses use
spawnwithshell: false, literal argument arrays, timeouts, and bounded capture. VirusTotal credentials are removed from spawned forensic-command environments. - Evidence is read-only. Mount it read-only in Docker/production. Run the server in a constrained VM or container because parsers can still have vulnerabilities.
- The log is append-only only from this process's perspective. Protect its directory and retention policy as part of chain of custody; an administrator can still alter files outside this application.
- Metadata can be absent, rewritten, or falsified. IP/URL/keyword strings, Volatility output, and VirusTotal counts require human review.
This repository does not include real case evidence, a real Windows memory dump, credentials, node_modules, build output, logs, or local Python environments. The tracked JPEG in tests/fixtures/ is a small harmless test fixture only.
Troubleshooting
| Symptom | Cause and action |
|---|---|
| Server appears to hang in a terminal | Normal for a stdio MCP server. Launch it through a client or run npm run verify:mcp; use Ctrl+C to stop a direct test launch. |
SUBPROCESS_BINARY_NOT_FOUND |
Install the forensic utility or set the relevant *_BINARY variable to an absolute executable path. |
PATH_OUTSIDE_EVIDENCE_ROOT |
The requested path resolves outside the configured root, including via a symlink. Put authorized evidence inside EVIDENCE_ROOT and retry with its canonical path. |
ANALYSIS_LOG_FAILED |
Ensure the parent directory of ANALYSIS_LOG_PATH is writable; use a persistent Docker bind mount at /app/data. |
extensionMismatch: true |
Investigate the bytes and provenance. It is not, by itself, a malware finding. |
resultsTruncated: true |
Treat strings output as incomplete; adjust limits only with an explicit resource/security review. |
| Memory plugins fail or are unavailable | Confirm a compatible Windows dump, Volatility version, symbol availability, executable path, and VOLATILITY_TIMEOUT_MS. Failed plugins are intentionally not turned into empty clean results. |
| Docker cannot read evidence | Check Docker Desktop file sharing and use an absolute host path. Keep the /evidence mount read-only. |
| Codex/Claude Code cannot start the server | Build first, use absolute paths to node/dist/index.js and runtime files, then restart/reload the client and inspect its MCP status panel. |
VirusTotal returns not configured |
This is intentional without VIRUSTOTAL_API_KEY; add a key only if hash sharing is authorized. |
Repository layout
.
├── src/ # NitroStack server, analyze and memory modules
├── src/widgets/ # analysis-report widget source
├── resources/ # expected-MIME reference data
├── scripts/ # Linux environment setup and MCP verifier
├── tests/ # unit, integration, and harmless fixtures
├── data/.gitkeep # runtime log directory placeholder
├── Dockerfile # Debian/Node 24 runtime
├── SECURITY.md # deployment/security review
└── AGENTS.md # contributor/harness operating guidance
No open-source license is included yet. Add a license file before representing the repository as reusable open-source software.
Installing Forensic Artifact Investigator
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/guyoverclocked/forensic-analyzer-mcpFAQ
Is Forensic Artifact Investigator MCP free?
Yes, Forensic Artifact Investigator MCP is free — one-click install via Unyly at no cost.
Does Forensic Artifact Investigator need an API key?
No, Forensic Artifact Investigator runs without API keys or environment variables.
Is Forensic Artifact Investigator hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Forensic Artifact Investigator in Claude Desktop, Claude Code or Cursor?
Open Forensic Artifact Investigator on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
GitHub
PRs, issues, code search, CI status
by GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
by mcpdotdirectCompare Forensic Artifact Investigator with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All development MCPs
