Stats Explorer MCP
[Stats Explorer MCP: verified statistics your AI assistant calls instead of guessing numbers]
An MCP server with 18 statistics and analytics tools an AI assistant can call instead of guessing numbers, on data files of any size:
- Tests: t-tests, z-tests, ANOVA (with a Tukey HSD post-hoc that names the groups that differ), ANCOVA, MANOVA, chi-square, Fisher's exact, binomial and correlation.
- A/B testing: A/B and A/B/n readouts for conversion rates and revenue-type metrics (lift with intervals, sample ratio mismatch check, Holm-adjusted comparisons, Bayesian probability to beat the control, segment breakdowns), and sample-size planning.
- Analytics: totals, averages and counts by category (top N), and "what drives X?" rankings across every column.
- Helpers: descriptive stats, confidence intervals, power analysis, a "which test should I use?" tool, and a data-file inspector.
The tools can read a developer's CSV, TSV, Excel or Parquet files by column name, so large datasets never get pasted into the chat. Each result includes:
- the effect size and confidence interval,
- a plain-English interpretation,
- warnings when an assumption looks shaky.
On top of that:
- Correct. 43 reference cases are checked against SciPy and statsmodels on every commit, to at least 6 significant figures.
- Guided by default. The agent first decides whether your request needs a hypothesis test or just exploration. Hypothesis tests follow the six steps of Stats Explorer's Bring it all together guide, in order.
- You stay in control. Every column, group, chart type and report section the agent proposes is shown to you to confirm or change before anything runs.
- Private. Runs locally over stdio. It makes no network calls and needs no API key (unless you turn on Jev's enforce mode, below). Data files are read only from your workspace folders.
- Checked by Jev, if you want. Connect Jev, TypeSafe's fast judgment model, alongside it, and Jev independently checks the test plan and the assistant's written conclusions against the computed results. You can run it without an orchestrator, enforced by Stats Explorer itself, or under a production orchestrator that signs every decision.
The engine, the file import and the six-step guide are shared with the Stats Explorer app, so results match the app exactly.
Connect it (pick your assistant)
GitHub Copilot in VS Code: about 1 minute, nothing else to install
- In VS Code, open Extensions (Ctrl+Shift+X / Cmd+Shift+X), search Stats Explorer MCP, click Install.
- Open Copilot Chat and switch the mode dropdown to Agent.
- Click the tools icon in the chat box and check that Stats Explorer is listed and ticked.
- Open the folder that holds your data and ask a question (see Example questions).
The extension registers the server itself, using VS Code's built-in runtime, so you don't need Node.js or an mcp.json file. Confirmations appear as forms you can edit.
Claude Code (terminal or the Claude Code panel in VS Code): about 2 minutes
You need Node.js 22 or later (24 LTS recommended). In a terminal, run this once:
claude mcp list should show stats-explorer … ✓ Connected. Then start a new Claude session, because servers are loaded when a session starts. In VS Code: Ctrl+Shift+P → Developer: Reload Window, then New session. Type /mcp in the chat to see the servers the session has.
-s user makes it available in every folder (without it, only in the folder where you ran the command).
STATS_EXPLORER_CONFIRM_VIA=chat makes confirmations appear as messages in the chat, which you answer by replying. Claude Code doesn't always display form-style prompts.
- If you have the VS Code extension installed, Stats Explorer: Copy Setup Command for Claude Code copies this command for you.
Claude Desktop, Cursor, Windsurf, Cline and other MCP clients
Add this to the client's MCP config (claude_desktop_config.json, .cursor/mcp.json, and so on), then restart the client:
Requires Node.js 22 or later. STATS_EXPLORER_ROOTS is the folder (or folders) the tools may read; see Data files.
Example questions
Name the file in your message (or attach it); the assistant passes it to the tools and never pastes the data into the chat.
- What's in sales.csv?
- Total revenue by state in sales.csv, top 10. (group_summary)
- What drives profit in sales.csv? (find_relationships, then follow-ups)
- Show the distribution of order value and a box plot by segment.
- Does average profit differ between the Consumer and Business segments? Is it significant? (six-step hypothesis test)
- Did the new checkout page (variant B) increase conversion in experiment.csv? Break it down by device. (ab_test)
- How many visitors do I need to detect a 10% lift on a 4% conversion rate, with 3,000 visitors a day? (ab_test_plan)
- Does revenue differ between the three regions, and which ones? (ANOVA + Tukey HSD)
- Make an HTML report of what we found and save it as findings.html.
The analyze, explore_data and hypothesis_test prompts (slash commands in VS Code and Claude) start the same flows.
Working with Jev (optional)
When both Stats Explorer and a Jev MCP server are connected to Claude or Copilot, they split the work. Stats Explorer computes every number, and Jev checks two things before you see a result:
- The test plan: is this the right test, are the hypotheses right, are these the right columns?
- The written conclusions: does every number match, is "significant" stated correctly, are there claims of cause the analysis can't support?
Stats Explorer also runs its own number and significance checks on every claim. Only claims that pass go into reports, and each report lists every check under Independent checks.
Quick start with Claude Code (no orchestrator):
Any Jev MCP server works (@jkudish/jev-mcp, jev-mcp, typesafe-mcp, …): the packets come in the shapes their tools take. In VS Code, set Stats Explorer › Jev: Mode. See docs/JEV.md for every mode and setting, the signed-approval format (with JavaScript and Python), what is sent to Jev, and the runnable orchestrator example in examples/orchestrator/.
How it works (default)
1. The agent classifies your request
Every analysis starts with start_analysis, where the agent picks a mode:
If it's unclear, the agent is instructed to ask you. Nothing else runs until start_analysis has been called.
2. Hypothesis tests follow the six steps, in order
Calling a step out of order is refused with a message that names the next step. Only steps 4 and 6 can be skipped, and only with a reason that appears in the report. If step 2 shows the chosen test doesn't fit, re-stating the plan in step 1 is allowed and restarts the later steps. The app's guide calls this a principled revision, not p-hacking.
[A hypothesis-test write-up: question, hypotheses, assumption checks, power, result and verdict]
3. You confirm every selection
When the agent proposes columns, groups, a chart type or report sections:
- Clients that support MCP forms (elicitation), such as VS Code, show you a form with the agent's choices pre-filled as dropdowns and checkboxes. Change anything, then accept or decline. Declining runs nothing.
- Other clients get a
CONFIRMATION NEEDED response listing the proposal, the alternatives and a one-time token. The agent is instructed to show you the choices and call again with the token only after you agree. A token only works for the exact selection it was issued for, so a changed selection is proposed again.
A selection you've confirmed isn't asked about twice in the same session.
4. Charts and reports
create_visualization: histogram, box plot, scatter (with least-squares line), bar (mean or count by category), line, and pie. These are the app's chart types. Returns an accessible SVG (light and dark mode) and can save it as .svg.
build_report: only when you ask for one, and containing only the sections you tick. A completed hypothesis test becomes a write-up in the app's format: the question, the hypotheses, how it was tested (with steps 2–4), what was found, the verdict and base rates. Explorations never get a hypothesis section. Saved as HTML (default) or Markdown in your workspace; existing files are not overwritten unless you say so.
[Charts: box plot, histogram, scatter with fitted line, and bar chart]
[An exploration report with summary statistics, a confidence interval and a histogram]
Images show real output on a sample dataset.
Tools
Tests available in step 1: t-test (one-sample, paired, Welch or Student), z-test (mean with known σ, proportion), one-way ANOVA (with a Tukey HSD post-hoc, plus optional Bonferroni Welch pairs), ANCOVA, MANOVA, chi-square (goodness of fit, independence), Fisher's exact, exact binomial, correlation and A/B test.
ANOVA post-hoc (Tukey HSD). Every one-way ANOVA with 3 or more groups includes Tukey's HSD (Tukey–Kramer for unequal group sizes), on in-memory and very large files alike: the difference, adjusted p-value and simultaneous interval for every pair, the significant pairs marked ★ ("B > A"), the best group and whether it beats all others, and a letter display (groups sharing a letter don't differ). Reports name the groups that differ.
A/B tests (ab_test). From inline numbers or a file with a variant column and an outcome column:
metric: "conversion" (converted yes/no): two-proportion z-test, with Fisher's exact p when counts are small. metric: "continuous" (revenue, time, order value): Welch's t-test.
- Every variant against the control: absolute lift (percentage points) and relative lift, each with an interval; Cohen's h or d.
- Sample ratio mismatch check against the planned split (
expected_split): a broken assignment blocks the decision.
- A/B/n: an omnibus test (chi-square, or ANOVA with Tukey HSD) and Holm-adjusted p-values (or Bonferroni / none).
- Bayesian view: probability each variant beats the control, probability of being best and the expected loss of shipping it (Beta-Binomial, computed by quadrature, so the numbers are reproducible).
- The minimum detectable effect of the test as run, an optional
mde (smallest lift that matters) to judge practical significance, an optional segment_column breakdown with a Simpson's-paradox warning, and a plain decision.
- In the guided workflow, step 2 adds the sample ratio check and step 4 sizes power in lift terms.
The server also offers the prompts analyze, hypothesis_test and explore_data, which clients such as VS Code show as slash commands.
Data files
Stats Explorer is built for tabular formats (CSV, TSV, Excel and Parquet) to run hypothesis tests or explore statistics. Files are read with the app's own import code:
- quoted fields, embedded commas and line breaks, BOMs, and tab, semicolon or pipe separators;
- missing values (blank, NA, N/A, null, #N/A, …) are skipped;
- numbers are parsed strictly (
"12 kg" is text, not 12), while 1,234, $12.50 and 45% still count as numbers;
- dates become
YYYY-MM-DD text;
- duplicate column names are renamed rather than overwritten;
- Excel serial dates are converted;
- Parquet files compressed with Snappy, gzip, zstd, Brotli or LZ4 are all read.
There is no size limit for CSV, TSV and Parquet files; see Large files.
JSON, BSON, NDJSON and NoSQL databases (MongoDB, CouchDB, Redis connection strings, …) are document data, not tables. For these, every tool answers with that statement and suggests exporting to CSV or Parquet first (for example mongoexport --type=csv). Inline rows containing nested objects or arrays get the same answer.
Files are read only from allowed folders, and symlinks that point elsewhere are refused:
STATS_EXPLORER_ROOTS, if set (separated by : on macOS/Linux, ; on Windows), otherwise
- the workspace roots your MCP client reports, otherwise
- the server's working directory.
Large files (gigabytes to terabytes)
Files up to 512 MB are loaded into compact column storage (a 190 MB, 1,000,000-row CSV loads in about 8 seconds using under 0.5 GB of memory). Larger CSV, TSV and Parquet files have no size limit. They are streamed instead, in a single pass that every tool needs:
- One pass, fixed memory. Each tool reads only the columns it uses, in parallel pieces (one per CPU core), and keeps running totals: counts, means, variances, sums of squares and cross-products. Memory does not grow with the file: about 0.5 GB with one reader, plus about 0.2 GB per extra parallel reader. A 2.5 GB, 13-million-row CSV took 45 seconds on 1 core and 22 seconds on 2; the same data as a 340 MB Parquet file took 9 seconds.
- Exact where it can be. t-tests, z-tests, ANOVA (with pairwise comparisons), ANCOVA, MANOVA, chi-square, Fisher's exact, Pearson correlation, means, standard deviations, skewness, kurtosis and confidence intervals are exact on every row. Groups of up to 100,000 values keep their actual values, so everything about them is exact, medians included.
- Estimated where it must be, and labelled. Medians, quartiles, histogram bars and outlier counts of larger groups come from a KLL quantile sketch (rank error about 0.03% in testing). Spearman's ρ comes from a random sample of 100,000 pairs, and
inspect_data_file's count of different values in a column, above 10,000, from HyperLogLog (within about 2%). Results that contain estimates list them in large_file.approximate and in their warnings.
- Asked first. If reading the whole file would take more than 2 minutes, you are asked whether to read every row (exact) or a quick sample of about 1% of the rows in blocks spread across the file (fast, approximate). Clients with forms show the choice as a form; otherwise the assistant asks you and calls
large_file_plan.
- Runs in the background. A read that takes longer than 40 seconds continues as a background job; the tool answers
STILL RUNNING with a job_id, and job_status returns the result when it's ready (with progress and time left meanwhile). cancel_job stops it. Clients that support MCP progress notifications see a progress bar.
- Read once. The workflow steps share one pass: step 1 reads the file, and steps 2 to 5 reuse the totals. With your consent, the columns read can be kept on disk (8 bytes per number, 4 per text value), so later questions on them take seconds.
manage_cache lists or deletes them.
- Same rules as small files. The streaming reader applies the app's import rules exactly. It was checked against the in-memory reader on 24 edge-case files and 300 random ones, and on 228 tool calls (tests, charts and full six-step workflows) across CSV and Parquet files, split into as many as 3 parallel pieces. Line breaks inside quoted values are handled: if a split point falls inside one, the file is re-read in one piece.
Excel files are always read whole (up to about 1.9 GB); export very large workbooks to CSV or Parquet.
Configuration
Accuracy
test/reference/generate.py computes expected values with SciPy and statsmodels for 43 cases. They cover every test and alternative, Welch and Student t-tests, p-values below 1e-30, ties in Spearman, ANCOVA (Type II SS), MANOVA with 2 and 3 outcomes, and file inputs with missing values. test/reference/guided.json adds the ANCOVA slope-equality F test and the step-4 power calculations (two-sample, one-sample, proportion and correlation), checked against statsmodels. test/reference/abtest.py checks Tukey HSD (studentized range, adjusted p-values, intervals and rejections against scipy.stats.tukey_hsd and statsmodels' pairwise_tukeyhsd) and every A/B number: z, p and one-sided p (proportions_ztest), lift intervals (confint_proportions_2indep), Wilson intervals, Fisher's exact, chi-square, Holm/Bonferroni (multipletests), the sample ratio check, Welch t-tests, the Bayesian probabilities and expected loss (numerical integration in SciPy) and sample sizes (NormalIndPower). npm test runs everything through real MCP clients over stdio (with and without form support) and requires agreement to a relative error of 1e-6.
Known approximations, also stated in the results:
- power uses the normal approximation (within about 0.01 of exact power, matching statsmodels'
NormalIndPower);
- Spearman p-values use the t approximation (as SciPy does);
- chi-square tests use no continuity correction;
- on very large files, medians, quartiles, histogram bars, outlier counts and Spearman's ρ are estimated (see Large files).
Limits worth knowing
- Confirmation forms appear only in clients that support MCP elicitation. Elsewhere the token flow relies on the agent relaying the proposal to you, as the server instructs. A token can't be guessed, and it can't be reused for a different selection.
- Which mode a request needs is decided by the agent, guided by the server's instructions. If it picks the wrong one, say so; it can start a new analysis.
Development
src/engine/ is copied from the Stats Explorer app by npm run sync-engine -- <path-to-app>: the statistics, the data import module and the Learn tab's workflow text. Fix them in the app and re-sync, so the two never drift.
License
MIT