autopsy-mcp
by th0r10293847
README.md
# autopsy-mcp
**Read-only MCP (Model Context Protocol) server** that exposes the data of an **Autopsy** case as standard Tools, usable from the **Cline** chat in VS Code (or from any other MCP client). The server is fully LLM-agnostic: it receives JSON arguments from tool calls and returns case-database data — all calls to OpenAI, Anthropic, Ollama etc. remain entirely on Cline's side.
## Requirements
- Python 3.10+
- An Autopsy case on disk (a folder containing `autopsy.db`), or a multi-user PostgreSQL deployment
- The Cline extension in VS Code
## Installation
```bash
git clone https://github.com/th0r10293847/autopsy-mcp.git
cd autopsy-mcp
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt # Windows: .venv\Scripts\pip install -r requirements.txt
```
Alternatively, the `start.sh` (Linux/macOS) and `start.bat` (Windows) scripts create the venv and install dependencies automatically on first run.
## Configuring the default cases directory
The server looks for cases in the directory pointed to by the **`AUTOPSY_CASES_DIR`** environment variable (default: `~/AutopsyCases`). A "case" is any subfolder containing `autopsy.db`. You can set it in three ways, in order of precedence:
1. As an argument to the start script: `./start.sh /path/to/cases`
2. As an environment variable in your shell: `export AUTOPSY_CASES_DIR=/path/to/cases`
3. In the `env` block of `cline_mcp_settings.json` (recommended for use with Cline — see below)
You can always open a case outside the default directory by passing its full path to the `set_active_case` tool, or pass an alternative directory to `list_cases`.
### PostgreSQL backend (multi-user cases)
For multi-user cases set `AUTOPSY_DB_BACKEND=postgresql` together with `AUTOPSY_PG_HOST`, `AUTOPSY_PG_PORT`, `AUTOPSY_PG_USER`, `AUTOPSY_PG_PASSWORD`, and install the driver: `pip install psycopg2-binary`. In this mode `set_active_case` accepts the **database name** of the case (visible in Autopsy under *Case → Case Properties*). The session is opened with `default_transaction_read_only=on`.
## Connecting to Cline
In VS Code open: Cline icon → **MCP Servers → Configure MCP Servers** (the `cline_mcp_settings.json` file) and paste the content of the `cline_mcp_settings.json` included in this project, adjusting the two paths:
- `args`: absolute path to `server.py` (use the venv's Python as `command` if you prefer: `.../autopsy-mcp/.venv/bin/python` or `...\\.venv\\Scripts\\python.exe`)
- `env.AUTOPSY_CASES_DIR`: your cases directory
Cline will launch the server on **stdio** automatically; you don't need to keep it running yourself. `autoApprove` is optional and only includes pure read tools.
## Exposed Tools
| Tool | Description |
|---|---|
| `list_cases` | Lists the cases (folders with `autopsy.db`) in the base directory |
| `set_active_case` | Sets the active case for the session |
| `get_case_summary` | Summary: creation date, examiner, data sources, file/artifact counts |
| `browse_filesystem` | Walks the `tsk_files` tree (roots → directories → files, with pagination) |
| `query_blackboard_artifacts` | Queries the Blackboard by type (web history, email, EXIF, chat…); without arguments it lists the available types with counts |
| `search_keywords` | Text search across file names and/or artifact content |
| `get_file_metadata` | Full metadata of a file by `obj_id`: hashes, MAC times, size, MIME, notable status |
Typical chat flow in Cline: *"List the available cases"* → *"Open case XYZ"* → *"Give me a summary"* → *"Search for the word 'bitcoin' in the artifacts"* → *"Show me the web history"*.
## Read-only guarantees (chain of custody)
- **SQLite**: connection opened with the URI `file:...?mode=ro`. The driver rejects any `INSERT/UPDATE/DELETE/DDL` at the engine level.
- **PostgreSQL**: session with `default_transaction_read_only=on` + `set_session(readonly=True)`.
- The code contains no write statements and never touches the files in the case folder; no tool accepts arbitrary SQL from the LLM — all queries are predefined and parameterized.
Note: for a repeatable examination it remains good practice to work on a **copy** of the case, and not on a case while Autopsy is running an ingest (the DB may be temporarily `locked`; in that situation the server returns a descriptive error and you can simply retry).
## Error handling
All errors are returned as JSON `{"error": "..."}` with hints that enable LLM self-correction: for example, a non-existent artifact type returns the list of types available in the case, and a `no such table` error includes the list of tables actually present (useful across different Autopsy schema versions).
## Quick test without Cline
```bash
export AUTOPSY_CASES_DIR=/path/to/cases
.venv/bin/python -c "import server; print(server.list_cases())"
```
## Automated tests
The project ships with a pytest suite (`tests/`) that verifies: all 7 tools against a realistic synthetic case, the self-explanatory error messages, the driver-level rejection of INSERT/UPDATE/DELETE/DDL, the **invariance of the SHA-256 hash of `autopsy.db`** after running all the tools (chain of custody), and a real MCP session over stdio (the same protocol used by Cline).
```bash
pip install pytest pytest-asyncio
pytest -v
```
For a manual try without a real case, generate the demo case:
```bash
python tests/make_fixture.py ~/AutopsyCases/DemoCase
```
A GitHub Actions workflow is also included (`.github/workflows/tests.yml`) that runs the suite on Linux and Windows, Python 3.10 and 3.12, on every push.
---
*Author: [th0r10293847](https://github.com/th0r10293847) — Copyright (c) 2026, released under the [MIT License](LICENSE).*
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues