dataframe-detective-mcp
# dataframe-detective-mcp
An [MCP](https://modelcontextprotocol.io) server that lets any MCP client (Claude Desktop, Claude Code, Cursor, ...)
load tabular files, profile them and answer questions with **sandboxed pandas code**. Extracted from the
[Mistral Data Detective](https://github.com/Giorgio089/mistral-data-detective) multi-agent project.
The client's own LLM writes the pandas code; the server only validates and executes it.
| Tool | What it does |
|---|---|
| `load_dataset(path, name?, clean_numbers=True)` | Load CSV/TSV/Excel/JSON/Parquet from the allowed root; converts `"1.234,50 €"` / `"12%"` to numbers |
| `list_datasets` / `unload_dataset` | Manage datasets held in memory (max. 20) |
| `describe_dataset(name)` | Schema, ranges, example values, first rows |
| `profile_dataset(name)` | Missing values, duplicates, outliers, correlations, skew, top/bottom categories (via [dataframe-autoprofile](https://github.com/Giorgio089/dataframe-autoprofile)) |
| `query_dataset(name, code, timeout_seconds?)` | Run pandas code in a restricted subprocess (via [safe-pandas-exec](https://github.com/Giorgio089/safe-pandas-exec)); answer goes into `result` |
## Install & configure
```bash
pip install git+https://github.com/Giorgio089/dataframe-detective-mcp
```
Claude Desktop / Claude Code config:
```json
{
"mcpServers": {
"dataframe-detective": {
"command": "dataframe-detective-mcp",
"env": { "DDMCP_ROOT": "/path/to/your/data" }
}
}
}
```
| Env var | Default | Meaning |
|---|---|---|
| `DDMCP_ROOT` | current directory | Only files below this directory can be loaded (symlinks are resolved) |
| `DDMCP_MAX_FILE_MB` | `50` | Maximum file size |
## Security
Files outside `DDMCP_ROOT` and unknown file types are refused. Code from `query_dataset` is validated and run in a
resource-limited subprocess, which is defence in depth and **not** a hard security boundary; see the security notes in
[safe-pandas-exec](https://github.com/Giorgio089/safe-pandas-exec#security-model---please-read). Do not point this at
data or clients you do not trust without additional isolation (container, no network).
MIT licensed.
TDQS
Scored across 6 tools
Each tool has a fairly distinct role: load/unload/list manage dataset lifecycle, describe vs profile inspect content, and query runs arbitrary code. The main ambiguity is between describe_dataset and profile_dataset, which both summarize a dataset, though the descriptions differentiate schema/stats from rule-based findings.
All tools follow a strict verb_noun snake_case pattern (load_dataset, list_datasets, unload_dataset, describe_dataset, profile_dataset, query_dataset). The naming is predictable and the resource (dataset) is constant across tools.
Six tools is well-scoped for an in-memory dataframe analysis server. Each tool covers a distinct lifecycle or inspection action with no obvious redundancy or bloat.
The surface covers the full load/list/describe/profile/query/unload lifecycle and query_dataset acts as an escape hatch for arbitrary analysis. Minor gaps exist around exporting/saving results or persisting derived datasets, but core workflows are covered.