hidim
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@hidim describe data/returns.parquet and tell me which factors matter"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
hidim-mcp
A local MCP server ("connector") that lets Claude work with high-dimensional data without the data ever entering the conversation.
The model cannot read a 10,000 x 512 matrix; it reads text and images. So the data stays inside this server process and Claude gets back only what fits through the straw:
Claude asks for | hidim returns |
"what is this dataset?" | schema, per-feature stats, missingness, identifier / label-like columns, duplicated features, effective rank, PCA variance curve on both raw and standardized scales, the number of factors above the Marchenko-Pastur noise edge, intrinsic dimension (TwoNN + MLE), distance-concentration and hubness diagnostics, and one consistent hint |
"clean it up first" |
|
"show me the structure" | an embedding (PCA / t-SNE / UMAP / Isomap / LLE / MDS / spectral / kernel PCA / random projection) stored server-side, with trustworthiness and explained variance, then a PNG scatter it can actually look at |
"which groups are there?" | k-means / GMM / DBSCAN / HDBSCAN / agglomerative labels, silhouette, centroid signatures |
"what is near this point?" | k nearest neighbours with distances and context |
"turn this long table into a cube" | a labelled N-d tensor (e.g. date x strike x maturity), readable through budgeted slices and reductions, plottable as heatmap / 3-D surface / lines, saved and reloaded as |
Every text result is capped (24k chars by default; tables 200 rows x 60 cols x 4000 cells) so a careless call cannot flood the context.
Scaling: the one default that matters
Most tools take standardize, and since 0.2.0 it defaults to "auto":
data whose columns share one unit (pixel intensities, read counts, [0, 1] images, spectra) is analysed on its raw scale. Z-scoring such data turns near-constant columns (border pixels, rare genes) into dominant features, inflates the condition number and roughly doubles the PCA rank (MNIST: 183 components for 90% standardized vs 86 raw);
heterogeneous columns (prices next to volumes next to ratios) are standardized;
every result says which scaling it used,
describeprints the PCA counts on both scales, andclip_z=10clips z-scores so that sparse or near-constant features cannot hijack k-means or kNN (True/Falseforce either choice).
describe also reports how many correlation eigenvalues sit above the Marchenko-Pastur noise edge. When that number is
small and the "components for 90% variance" count is large, the extra rank is noise (a return panel has 3-4 real factors
and 30 noise eigenvalues), and the hint says so instead of recommending t-SNE on noise.
Related MCP server: XLMCP
Install
Python 3.10+. Required: mcp, numpy, pandas, scipy, scikit-learn, matplotlib. Optional: umap-learn (UMAP), pyarrow (parquet/feather), openpyxl (xlsx), h5py (HDF5), xarray + netCDF4 (NetCDF/Zarr).
cd hidim-mcp
python3 -m venv .venv && source .venv/bin/activate # or: uv venv && source .venv/bin/activate
pip install -e ".[all]" # or: pip install -e . (core only)
python -m hidim_mcp.server --help 2>/dev/null; python tests/stdio_smoke.py # end-to-end check (~20 s)Works with both mcp 1.x (FastMCP) and 2.x (MCPServer).
Connect to Claude Desktop
The short way (merges the entry into your existing config, backs the file up first, refuses to touch invalid JSON):
.venv/bin/python register.py # add --roots ~/data:~/research --out ~/hidim_out to change defaults
.venv/bin/python register.py --dry-run # preview; --remove takes it out againThe manual way:
Claude menu (menu bar) -> Settings... -> Developer -> Edit Config. On macOS this reveals
~/Library/Application Support/Claude/claude_desktop_config.jsonin Finder (Windows:%APPDATA%\Claude\claude_desktop_config.json); open it in a plain-text editor (straight quotes only; TextEdit's smart quotes break JSON).Merge the
"hidim"entry into the existingmcpServersobject (do not paste a secondmcpServerskey). Use absolute paths; the interpreter must be the one where you installed the package.
{
"mcpServers": {
"hidim": {
"command": "/Users/you/hidim-mcp/.venv/bin/python",
"args": ["-m", "hidim_mcp.server"],
"env": {
"HIDIM_ROOTS": "/Users/you/data:/Users/you/research",
"HIDIM_OUT": "/Users/you/hidim_out"
}
}
}
}Quit Claude Desktop completely (Cmd+Q) and reopen it. The tools appear under the "+" menu -> Connectors -> hidim.
If it does not connect:
tail -f ~/Library/Logs/Claude/mcp-server-hidim.logshows the server's stderr, and running thecommand+argsby hand in a terminal shows import errors. The config file must be valid JSON.
Connect to Claude Code
claude mcp add --transport stdio --scope user hidim \
-e HIDIM_ROOTS=/Users/you/data -e HIDIM_OUT=/Users/you/hidim_out \
-- /Users/you/hidim-mcp/.venv/bin/python -m hidim_mcp.serverEverything after -- is the server command. Claude Code warns above 10k tokens of tool output and truncates at 25k by default;
hidim's own caps keep well under that.
Configuration (environment variables)
Variable | Default | Meaning |
| home directory |
|
|
| where PNGs and exports go (always allowed) |
| 24000 | cap on any text result |
| 200 / 60 / 4000 | table rendering caps |
| 2e9 | refuse to build larger tensors |
| 20000 | scatter/pairs sample size |
| 20 | legend entries before rarer classes fold into 'Other' |
| 300 | points labelled by |
| 700000 | re-render at lower dpi above this |
| unset | set to |
Tools
Tool | What it does |
| what is in memory (name, kind, shape, memory, parent) |
| csv tsv txt parquet feather json jsonl xlsx npy npz mat h5 nc zarr -> table or tensor; returns only a schema |
| tables: csv parquet feather json npy xlsx mat; tensors: npz (round-trips dims+coords), npy, nc, mat |
| free memory |
| blobs, swiss_roll, s_curve, gaussian, lowrank, options_surface |
| the diagnostic profile described above (tables and tensors) |
| declare integer class codes / years / hours / lat-lon / ids as labels so they leave the feature matrix |
| log1p, log, sqrt, zscore (clip), minmax, clip, winsorize, rank, demean, detrend, diff, pct_change, log_return, cumsum, row_normalize, center_rows, deseasonalize, residualize, dropna -> new table |
| pandas-query filter, column selection, sampling; the only way to read raw rows |
`neighbors(name, index | point, k, metric)` |
| pca svd ica random kpca tsne umap isomap lle mds spectral -> stored embedding + metrics |
| full loading vector of a PCA component (level / slope / curvature shapes) |
| kmeans gmm dbscan hdbscan agglomerative -> label column + metrics; auto-k shows the whole silhouette-by-k table |
| long table -> labelled N-d tensor; natural sort of text axes, explicit |
|
|
| log1p, demean, zscore, diff, pct_change, log_return, cumsum, normalize, anomaly (climatology), area_weight, fillna -> new tensor |
| flatten time x lat x lon into time rows x gridpoint columns for PCA / EOF analysis |
| same-shaped tables/tensors -> one tensor with a new leading axis |
| read cells: exact / nearest / range / isin / positions / stride selection, NaN-aware reductions |
| PNG returned inline: scatter (2-D/3-D, legends up to 20 classes, colour bars for numeric and datetime columns, point labels), pairs, parallel, corr (labelled, clustered order), heatmap, scree, hist, andrews; tensor, surface (true axis values), lines |
A typical session
make_synthetic(kind="blobs", n=5000, d=128, k=6) -> 'synthetic_blobs'
describe("synthetic_blobs") -> rank 5 explains 90%, intrinsic dim ~40, hubness high ...
project("synthetic_blobs", method="tsne") -> 'synthetic_blobs__tsne2', trustworthiness 0.96
cluster("synthetic_blobs__tsne2", method="hdbscan") -> 6 clusters, silhouette 0.81, labels written back to parent
plot("synthetic_blobs__tsne2", kind="scatter", color_by="cluster_hdbscan") -> picture
neighbors("synthetic_blobs", index=17, k=5) -> who sits next to row 17 in 128-D
load_dataset("~/data/option_quotes.parquet", name="q")
tensorize("q", axes=["date","strike","expiry"], values=["iv","volume"]) -> 'q__tensor' date x strike x expiry x variable
slice_tensor("q__tensor", select={"variable":"iv","date":"2024-03-15"}) -> the surface for one day as a table
plot("q__tensor", kind="surface", select={"variable":"iv","date":"2024-03-15"}, log_axes=["expiry"])
plot("q__tensor", kind="lines", select={"variable":"iv","strike":{"nearest":100}}, series_dim="expiry")
tensor_transform("q__tensor", op="diff", dim="date", new_name="dq") -> daily surface changes
tensor_to_table("dq", row_dim="date", select={"variable":"iv"}, new_name="dq_rows")
project("dq_rows", method="pca", n_components=3, standardize=False) -> the level / term / skew modes of the surface
save_dataset("q__tensor", "~/data/iv_cube.npz") -> reloadable with load_dataset
load_dataset("~/data/sst.mnmean.nc", name="sst", options={"key": "sst"}) -> tensor time x lat x lon
tensor_transform("sst", op="anomaly", dim="time", params={"period": "month"}) -> seasonal cycle removed
tensor_transform("sst__anomaly", op="area_weight", dim="lat") -> cos(lat)^0.5 weights
tensor_to_table("sst__anomaly__area_weight", row_dim="time", select={"lat": {"range": [-30, 30]}, "lon": {"range": [120, 290]}})
project(<that table>, method="pca", n_components=3, standardize=False) -> EOF1 is ENSOWhat it deliberately does not do
It never returns a whole dataset.
subsetpreviews are capped;slice_tensorthins anything over the cell budget and says so.Memory lives in the server process. Restarting Claude Desktop restarts the server and empties it:
save_datasetwhat you want to keep.t-SNE, Isomap, LLE, spectral and MDS run on random samples by default (they are O(n^2)); PCA, SVD, UMAP and random projection scale to the full table.
It is a local tool for your own data.
subset(where=...)is evaluated by pandas' query engine, which is an expression language, not a security sandbox; the model is the caller, so do not expose this server over HTTP to clients you do not trust, and keepHIDIM_ROOTSto directories you are happy to have read and written.
Provenance
Idea and direction: Daniel Margolis. Design and implementation: written with Claude (Anthropic) in a single working session, November 2026, then run end to end over stdio against Claude Desktop. Version 0.2.0 followed a test battery of eleven real datasets with published answers (Treasury yield curve, SPX/SPY option surfaces, Fama-French 49 industries, sklearn digits and MNIST, UCI HAR, PBMC 3k single-cell RNA-seq, GloVe word vectors, Golub leukemia and Olivetti faces, Indian Pines and Pavia University hyperspectral cubes, NOAA ERSST sea-surface temperature, NYC taxi trips); the numbers matched independent scikit-learn runs everywhere, and every defect that battery exposed in the defaults, hints and plots is fixed here (see CHANGELOG.md). The intrinsic-dimension estimators follow Facco et al. (2017, TwoNN) and Levina & Bickel (2004, MLE); the concentration diagnostic follows Beyer et al. (1999); hubness follows Radovanovic et al. (2010); trustworthiness is scikit-learn's implementation of Venna & Kaski (2001).
Development
python -m pytest tests -q # unit tests of the engine (scaling, Marchenko-Pastur, hints, transforms, ordering, plots)
python tests/stdio_smoke.py # speaks JSON-RPC over stdio to a real server process and exercises every toolThe engine (hidim_mcp/engine.py) has no MCP dependency and can be driven directly from Python or a notebook.
Available Tools
20 toolsclusterA
Cluster a table (or an embedding) and add a label column (cluster_) usable as color_by in plot. If run on an embedding, labels are also written back to the parent table. methods: kmeans (k omitted -> silhouette over 2..k_max, with the whole silhouette-by-k table, the Calinski-Harabasz choice and the finest k within 10% of the best, because silhouette favours coarse splits), gmm (k by BIC), dbscan (eps from 5-NN distances), hdbscan, agglomerative. standardize 'auto'/True/False and clip_z as in project. Returns sizes (with a warning when clusters hold <0.5% of rows: outliers, not groups), silhouette, Davies-Bouldin and each cluster's centroid signature (features most displaced from the global mean, in SD units).
Inputs: name (required), k, seed, k_max, +6 more. Returns: result
describeC
Budgeted profile of a dataset. For tables: schema, label columns, identifier-like and label-like integer columns, per-feature stats, missingness, constant and duplicated features, plus high-dimensional geometry on a sample: strongest correlations, effective rank, condition number, PCA components needed for 50/80/90/95/99% variance (on the chosen scaling AND on the other one), the number of correlation eigenvalues above the Marchenko-Pastur noise edge (how many factors carry more than noise), intrinsic dimension (TwoNN and MLE), distance concentration and hubness. standardize: 'auto' (default) keeps raw scales for data in one shared unit such as pixels / counts / [0,1] intensities and z-scores heterogeneous columns; True/False force it. For tensors: dims, coordinate ranges, fill rate per axis, value distribution. Ends with one consistent hint on what to do next.
Inputs: name (required), seed, sample, standardize, +1 more. Returns: result
drop_datasetC
Remove a dataset from memory.
Inputs: name (required). Returns: result
list_datasetsA
List datasets currently held in memory: name, kind (table|tensor), shape, memory, parent, how they were made.
Inputs: no named parameters. Returns: result
load_datasetA
Load a file into memory as a table (rows x columns) or tensor (N-d labelled array). Returns a schema summary, never the data.
Formats by extension (or format): csv tsv txt parquet feather json jsonl xlsx npy npz mat h5/hdf5 nc zarr.
options: pandas/reader keyword arguments, e.g. {"sep": ";", "index_col": 0, "parse_dates": ["date"]}, {"sheet": "Sheet2"},
{"key": "array_name"} for npz/mat/h5/nc with several arrays. Relative paths resolve against the first HIDIM_ROOTS entry (home by default).
npz files written by save_dataset come back as tensors with their dims and coordinates intact.
Inputs: path (required), name, format, options. Returns: result
loadingsA
Loading vector of one principal component of a PCA embedding made by project(method='pca'): the strongest positive and negative features, or the whole vector in feature order (all_features=True) to read shapes such as level/slope/curvature.
Inputs: name (required), top, component, all_features. Returns: result
make_syntheticB
Create a synthetic dataset for demos and sanity checks.
kinds: blobs (k Gaussian clusters in d dims, label column), swiss_roll / s_curve (2-D manifold embedded in d dims, colour column t), gaussian (iid noise: the null model for the diagnostics), lowrank (rank-k matrix plus noise), options_surface (long table date x strike x maturity_days -> iv, spot, volume; for tensorize demos).
Inputs: d, k, n, kind, +3 more. Returns: result
neighborsA
k nearest neighbours of one row (index = row label or integer position) or of an explicit point (vector in feature order), in the original high-dimensional space. Returns distances, positions and a few columns of each neighbour, plus how those distances compare with the distance to a random row (relative contrast). metric: any scikit-learn metric (euclidean, cosine, manhattan, ...); cosine is usually the right choice for embeddings and other hub-prone spaces. standardize: False (default), True or 'auto'.
Inputs: name (required), k, index, point, +4 more. Returns: result
plotA
Render a PNG picture (returned as an image you can look at; also saved under HIDIM_OUT) with a one-line caption.
Tables: scatter (x,y[,z]; defaults to the first components of an embedding; color_by a label/cluster/numeric/datetime column, parent columns of an embedding work too: categories get a legend of up to 20 classes, numeric and datetime columns a colour bar; annotate= writes that column's value next to each point, up to 300 points), pairs (scatter matrix of <=6 features), parallel (parallel coordinates, min-max scaled), corr (correlation heatmap with feature labels, reordered by hierarchical clustering so correlated blocks are visible; order='given' keeps table order), heatmap (raw value matrix rows x columns), scree (PCA variance curve, auto scaling), hist (small-multiple histograms), andrews (Andrews curves by class). Tensors: tensor (heatmap of a 2-D slice), surface (3-D surface of a 2-D slice; numeric and datetime axes are drawn at their true values, log_axes=['maturity_days'] draws a dim on a log10 scale), lines (1-D slices over one dim, up to 12 series from series_dim; use select={'dim': {'isin': [...]}} to pick). Use select/reduce exactly as in slice_tensor to get down to 2 dims (or 1-2 for lines). Large tables are randomly sampled to HIDIM_PLOT_MAX_POINTS (20000) points; categorical colours beyond HIDIM_MAX_CLASSES (20) fold into 'Other'.
Inputs: name (required), x, y, z, +15 more.
projectA
Reduce a table's numeric features to n_components and store the embedding as a new table (name__method) with label, datetime and cluster columns carried over for colouring. Returns quality metrics, not coordinates.
methods: pca (explained variance, top loadings; full vectors via loadings()), svd, ica, random (Gaussian random projection), kpca, tsne, umap (needs umap-learn), isomap, lle, mds, spectral. Non-linear methods run on a random sample (default caps: tsne 5000, umap 50000, isomap/lle/spectral 5000, mds 2000; override with sample) and get an automatic PCA to 50 dims first when there are more than 50 features (pre_pca). params passes method-specific keywords (perplexity, n_neighbors, min_dist, kernel, metric, ...). standardize: 'auto' (default; raw scales for pixel/count/[0,1] data, z-scores otherwise), True or False. clip_z=10 clips z-scores so near-constant or sparse features cannot dominate. Every method reports trustworthiness (1.0 = neighbourhoods perfectly preserved). ascii=True adds a coarse text density map.
Inputs: name (required), seed, ascii, clip_z, +8 more. Returns: result
save_datasetB
Write a dataset to disk under HIDIM_ROOTS. Tables: csv parquet feather json npy xlsx mat. Tensors: npz (keeps dims+coords, reloadable), npy, nc (needs xarray), mat.
Inputs: name (required), path (required), format. Returns: result
set_labelsA
Declare columns of a table as labels / coordinates (integer class codes, year, hour, lat, lon, ids): they are excluded from the feature matrix used by describe/project/cluster/neighbors and stay available for color_by and annotate. unset=True reverses it.
Inputs: name (required), columns (required), unset. Returns: result
slice_tensorA
Read part of a tensor. select maps dim -> scalar (exact, or nearest for numeric/datetime axes), list (several values), {"range": [lo, hi]}, {"isin": [...]}, {"nearest": v}, {"iloc": [start, stop]}, {"positions": [...]}, {"every": n}. reduce maps dim -> mean|std|var|sum|min|max|median|count|first|last (NaN-aware). Scalar selections drop the dim. When 1 or 2 dims remain the values are returned as a table (evenly thinned if over max_cells, default 4000); with more dims you get summary stats and should select/reduce further. new_name stores the result (2-D or less becomes a table that describe/project/plot accept; otherwise a tensor).
Inputs: name (required), reduce, select, new_name, +1 more. Returns: result
stack_datasetsA
Stack several same-shaped tables (their numeric blocks) or tensors along a new leading dimension, e.g. one CSV per ticker -> ticker x row x column. Shapes and column sets must match exactly (use subset/tensorize to align first).
Inputs: names (required), labels, new_name, axis_name. Returns: result
subsetA
Filter / select / sample rows and columns of a table; preview a few rows; optionally store the result as new_name.
where: pandas query string, e.g. "iv > 0.3 and maturity_days <= 30" (backtick-quote odd column names). columns: list of names, "re:", or "top_variance:". top_variance keeps the k highest-variance numeric features. This is the only way to read raw rows; preview is capped (200 rows x 60 cols).
Inputs: name (required), seed, where, sample, +6 more. Returns: result
tensor_from_wideB
Turn a wide table whose column names encode several keys (AAPL_close, AAPL_volume, MSFT_close, ...) into a tensor index x dims..., splitting column names on sep. dims default to ['series', 'feature']. The wide table's column order is kept for the name-derived dims (so a tenor axis 1m,3m,6m,1y,2y stays in that order); sort=True sorts naturally instead, order={dim: [...]} pins an explicit order.
Inputs: name (required), sep, dims, sort, +3 more. Returns: result
tensorizeA
Condense a long/tidy table into a labelled N-d tensor: each column in axes becomes a dimension and each value column
fills the cells; several value columns add a trailing 'variable' dimension. Coordinates: numeric/datetime axes sort
numerically, text axes sort naturally (b2 before b10); sort=False keeps first-appearance order; order={'tenor': ['1m','3m','1y']}
pins an explicit order per axis. Duplicate axis combinations are aggregated with agg (mean|sum|first|last|max|min|median|count);
missing combinations become NaN. Note that a later reduce 'mean' over a dim averages cells, not underlying rows: to get a
row-weighted mean, tensorize agg='sum' and agg='count' and divide.
Example: tensorize('opts', axes=['date','strike','maturity_days'], values=['iv']) -> a date x strike x maturity volatility cube.
Inputs: axes (required), name (required), agg, sort, +3 more. Returns: result
tensor_to_tableB
Flatten a tensor into a table: one row per coordinate of row_dim, one feature column per combination of the other dims (time x lat x lon -> time rows x gridpoint columns). All-NaN columns are dropped; the row coordinate becomes a label column. select/reduce (as in slice_tensor) are applied first. Then describe/project/cluster it like any table.
Inputs: name (required), row_dim (required), reduce, select, +1 more. Returns: result
tensor_transformA
Preprocess a tensor into a new tensor. Elementwise: log1p, log (params offset), sqrt, abs, fillna (params value, or dim for a mean fill). Along dim: demean, zscore, diff / pct_change / log_return (params periods; the axis shrinks), cumsum, normalize (params target). anomaly (dim = a datetime axis, params period=month|dayofyear|dayofweek|hour|quarter, baseline=[start,end]) subtracts the per-period climatology -> anomalies. area_weight (dim = latitude axis in degrees, params power: 0.5 for PCA/EOF, 1 for means) multiplies by cos(lat)^power. Typical EOF chain: tensor_transform(op='anomaly', dim='time') -> tensor_transform(op='area_weight', dim='lat') -> tensor_to_table(row_dim='time') -> project(pca, standardize=False).
Inputs: op (required), name (required), dim, params, +1 more. Returns: result
transformB
Preprocess the numeric features of a table into a new table (labels, ids and datetimes carried over unchanged).
ops: log1p, log (params offset), sqrt, abs, clip (lo/hi or z), winsorize (q), rank, zscore (params clip), minmax, demean, detrend (params by), diff / pct_change / log_return / cumsum along rows (params periods, by=, group_by, dropna), row_normalize (params target; library-size normalization for counts), center_rows (subtract each row's mean: removes the equal-weight market / common mode of a panel), deseasonalize (params by=, period=month|dayofweek|hour|dayofyear|quarter: subtracts per-period means -> anomalies), residualize (params on=[cols]: regress every feature on those columns and keep residuals, e.g. remove a market factor), dropna. Typical chains: counts -> row_normalize -> log1p -> project(clip_z=10); prices -> log_return -> describe; monthly series -> deseasonalize -> project(pca, standardize=False).
Inputs: op (required), name (required), params, columns, +1 more. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 20 tools
Most tools have clearly distinct roles, and the table-versus-tensor split is consistently reflected in names and descriptions. The few overlaps are paired conversions (tensorize vs tensor_from_wide, tensor_to_table vs slice_tensor) where the descriptions help but an agent may still pause to choose.
Names are consistently snake_case and generally action-oriented, with predictable prefixes for tensor operations. There are minor deviations: some tools are bare verbs (plot, describe, transform, subset, cluster) while others are noun-like (loadings, neighbors), but the set remains highly readable.
Twenty tools is on the heavy side for a single server, but the scope is broad: loading/saving, profiling, plotting, preprocessing, dimensionality reduction, clustering, and tensor operations. Each tool earns its place, though the surface could be slightly tightened.
The lifecycle is well covered for datasets: create/load, inspect, transform, subset, save, and drop. Notable gaps remain for common table workflows such as joins/merges and explicit group-by aggregation, though some workarounds exist through tensorize and subset.
Maintenance
Related MCP Connectors
The all-in-one data stack for agents. Upload files, run SQL, evolve tables, and render charts.
Interactive data visualization and executive PDF dashboards for ChatGPT, Claude, and Cursor.
Explore, clean, transform and export your Mammoth Analytics data from an AI client.
Connect your ads, shop, analytics, social, CRM and finance platforms once, then let Claude, ChatGPT, Cursor or any MCP client read, join and explain your numbers. Public statistics from the World Bank, IMF, Eurostat, OECD, WHO and SEC filings come as context, searchable and chartable from the same tools. Read-only by design, every number carries its source.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables creating interactive data visualizations from natural language queries using DuckDB for local databases or Databricks for enterprise data warehouses. Supports multiple chart types, CSV imports, SQL queries, and automatic statistical analysis through Claude Desktop.19MIT
- AlicenseBqualityDmaintenanceEnables Claude Code to interact with Jupyter notebooks, perform semantic search over knowledge files, and manage research projects.334MIT
- FlicenseNot gradedqualityCmaintenanceEnables LLM clients to load, clean, visualize, and analyze tabular datasets, and to generate multi-format analytic reports through natural language instructions.-
- AlicenseAqualityCmaintenanceEnables read-only analytical access to local CSV, Parquet, JSON files or a DuckDB database through MCP, with table discovery, column profiling, guarded SQL querying, and explain plans for safe use with Claude Desktop and Claude Code.81MIT