MCP Server¶
No Code. Just Data and Insight.
The Pulsar MCP (Model Context Protocol) server lets AI clients—Claude, Gemini, Cursor, and others—analyze your data autonomously. You don’t need to write code, tune parameters, or understand Ball Mapper. Just point the AI at your CSV and ask for the story.
This guide is for domain experts who know what their data means but don’t want to write scikit-learn pipelines.
Workflow Comparison¶
Approach |
You Do |
AI Does |
Speed |
|---|---|---|---|
YAML-Driven (manual) |
Write YAML, run pipeline |
(nothing) |
Depends on grid size |
Programmatic (Python) |
Write Python, orchestrate |
(nothing) |
Depends on grid size |
MCP + Claude (recommended) |
Point AI at CSV, ask question |
Entire analysis workflow |
~2–30s (automated tuning) |
MCP is the fastest path from “I have a CSV” to “Here’s what it means.”
The Value Prop¶
Traditional clustering (K-means, DBSCAN): - You guess the number of clusters - Algorithm forces your data into spheres - You get a silhouette plot and hope for the best
Pulsar with Claude: - Claude probes your data’s geometry automatically - Finds true topological structure (manifolds, voids, networks) - Generates a statistical dossier (z-scores, trait profiles, separation metrics) - You read the story, not a confusion matrix
Claude handles all the messy parts: imputation, categorical encoding, parameter selection, and iterating when the results look wrong. Dedicated tools let Claude fix preprocessing errors in ≤2 tool calls before re-running the sweep.
Setup¶
Easy install (recommended)¶
Install uv, then register Pulsar with every agent tool you use:
uvx --from thema-pulsar pulsar install
The installer detects Claude Code, Claude Desktop, Codex CLI, Gemini CLI, GitHub Copilot CLI, Cursor, VS Code, and Google Antigravity. It writes the pulsar MCP entry each client expects, using an absolute path to uvx so GUI-launched apps can spawn the server. Inspect registrations with uvx --from thema-pulsar pulsar status; remove them cleanly with uvx --from thema-pulsar pulsar uninstall.
The prompt talks to your terminal directly, so it still appears when output is
redirected (pulsar install | tee install.log). Where escape codes will not
render (TERM=dumb) it falls back to a numbered list. Where there is no
terminal at all — CI, a systemd unit — pass explicit harness ids (claude,
claude-desktop, codex, gemini, copilot, cursor, vscode,
antigravity) or --all:
uvx --from thema-pulsar pulsar install --all
uvx --from thema-pulsar pulsar uninstall --all --yes
Manual per-client setup¶
Pulsar ships an MCP server entry point (pulsar-mcp) via the mcp extra of the published thema-pulsar package. You do not need to clone the repo or create a Python environment. If you prefer to configure clients by hand, choose your client below. uvx downloads the released package from PyPI and runs it in an isolated environment.
Note
Pulsar works with any MCP-capable client, including Cursor and Gemini CLI, where you can add Pulsar as an MCP server/tool.
Note
The first launch can take a little while. Pulsar is a substantial scientific server, and uvx may need to download the package and initialize its numerical dependencies before MCP tools appear. Wait for it to finish before retrying; later launches normally reuse uv’s cache.
The Gemini command below sets --timeout 60000 (60,000 milliseconds, or 60 seconds) so this first boot can complete. Clients that expose no timeout setting may give up before the download finishes — for those, either run the uvx command once in a terminal to warm uv’s cache before starting the client, or use a persistent install (see Alternative install methods) so there is nothing to download at launch.
Open ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows) and add:
{
"mcpServers": {
"pulsar": {
"command": "uvx",
"args": ["--from", "thema-pulsar[mcp]", "pulsar-mcp"]
}
}
}
Restart Claude Desktop. A hammer icon in new chats confirms the tools loaded.
Note
GUI-launched apps on macOS often don’t inherit your shell PATH. If Claude can’t find uvx, replace "command": "uvx" with its absolute path (find it with which uvx, e.g. /Users/yourname/.local/bin/uvx).
gemini mcp add --scope user --timeout 60000 pulsar uvx -- --from "thema-pulsar[mcp]" pulsar-mcp
The -- matters: it stops Gemini’s own argument parser from consuming --from. This user-scoped registration works from any directory and makes Pulsar available in every trusted Gemini workspace (see the trust note below). Use --scope project instead to limit it to the current project. The longer timeout gives uvx time to download and initialize Pulsar on its first launch.
Launch Gemini from the workspace containing your data, then run /mcp list to confirm Pulsar is connected.
Note
Workspace trust gates stdio MCP servers. As of Gemini CLI 0.53, Gemini does not start stdio MCP servers in an untrusted workspace, so a user-scoped Pulsar registration still stays dormant until you trust the folder. Choose Trust folder when first prompted; if you previously declined, run /permissions trust inside Gemini and select Trust folder. Let Gemini relaunch — running sessions do not reload external settings changes, so if it does not relaunch on its own, fully exit and start it again.
See Gemini CLI folder trust for what untrusted mode restricts and how to review your trust decisions. Note that on 0.53 the trust prompt appears without any opt-in, so ignore that page’s claim that the feature is disabled by default.
claude mcp add pulsar -- uvx --from "thema-pulsar[mcp]" pulsar-mcp
Open Settings → Features → MCP → Add new MCP server:
Name:
pulsarType:
commandCommand:
uvx --from "thema-pulsar[mcp]" pulsar-mcp
Alternative install methods¶
If you prefer a persistent install over ephemeral uv invocations:
pipx install "thema-pulsar[mcp]"
pulsar install --mode pipx
Or pip install "thema-pulsar[mcp]" in any venv, then point clients at pulsar-mcp directly (or run pulsar install --mode pipx from that environment).
Developing against a local clone¶
Contributors working on the Pulsar source can launch the server from a checkout instead:
uv sync --extra mcp
uv run pulsar-mcp
# or, equivalently, using the dev dependency-group:
uv run --group mcp pulsar-mcp
Point your MCP client at uv run --group mcp pulsar-mcp (with cwd set to the clone) for live-edit development.
Workflow¶
Once connected, give the AI a goal rather than instructions. The AI already knows the technical steps.
The recommended prompt:
“I have a dataset at
path/to/data.csv. Use Pulsar to find the hidden structure and tell me the story of this data. I’m looking for meaningful subgroups and the specific traits that define them.”
Under the hood the AI will:
Characterize geometry — probe k-NN distances and projection dimensions to ground parameter choices; on large datasets, may include a
minhash_advisorywith suggestedcosmic_graph.minhash_dthat agents can apply viarefine_configbefore expensive sweepsGenerate a preprocessing config — recommend impute/encode rules for every column with rationale
Validate preprocessing — dry-run the preprocessing stage before committing to a full sweep
Run a topological sweep — find the most stable version of the data’s shape
Iterate automatically — repair preprocessing errors and tune epsilon if results are degenerate
Generate a Dossier — statistical profiles of each discovered subpopulation
Available MCP Tools¶
The server exposes these tools to the AI client, which chains them together automatically. Call get_workflow_guide once at the start of a session for the full opinionated procedure — the tables below are a reference, not a sequence.
Core loop¶
Tool |
What It Does |
|---|---|
get_workflow_guide |
Returns the full end-to-end procedure as markdown. Opt-in — not injected into every session automatically. |
ingest_dataset |
Registers a host-visible CSV/Parquet path and returns the stable |
characterize_dataset |
Quick exploratory summary: k-NN distances (is your data sparse or dense?), projection dimensions, missing value patterns. On large datasets ( |
create_config |
Builds a baseline sweep config calibrated against the processed feature space (after preprocessing + scaling) for a given |
run_topological_sweep |
Execute the full Pulsar pipeline: imputation → projection → Ball Mapper → cosmic graph, from inline YAML or a session’s active config. Returns structured JSON with metrics and experiment diff. Config persistence is opt-in. Results cached per session. |
diagnose_cosmic_graph |
Current graph-state observables: scale, component morphology, weight distribution, sweep support, observed patterns, and risk factors. When |
refine_config |
Applies targeted dotted-path overrides (or key deletions) to a config instead of regenerating the whole YAML — the normal way to iterate after a diagnosis. |
generate_cluster_dossier |
Computes clusters on the interpretation-threshold slice and returns per-cluster statistical evidence: trait profiles, homogeneity scores, separation metrics, concentration measures, plus clustering method metadata (method used, silhouette score). Persists a |
compare_clusters |
Pairwise statistical tests (Welch’s t-test, Kolmogorov-Smirnov, Cohen’s d, effect sizes) between two cached clusters. Answers “Are these really different, or just noise?” |
export_labeled_data |
Return your original dataframe with labels from a specific |
Preprocessing helpers¶
Tool |
What It Does |
|---|---|
probe_columns |
Per-column drilldown (≤20 columns per call): sample values, missingness, distributions. Use after |
recommend_preprocessing |
Analyze column profiles and return a complete |
validate_preprocessing_config |
Dry-run only the preprocessing stage against the session data — no projection, no sweep cost. Returns PASS with a schema summary, or a structured error ready to pass to |
repair_preprocessing_config |
Parse a preprocessing error from |
validate_config |
Validates and normalizes a complete config into canonical YAML, independent of running a sweep. |
Sweep history and graph structure¶
Tool |
What It Does |
|---|---|
get_sweep_history |
The session’s sweep table plus pattern synthesis across runs — what’s been tried and how outcomes shifted. |
compare_sweeps |
Markdown diff of two persisted runs’ config and metrics. |
get_threshold_stability_curve |
The H0 persistence-stability curve, structural breakpoints, and candidate threshold “lenses” (balanced / report-ready / detail-seeking / outlier-mining) for choosing |
get_topological_skeleton |
Graph connectivity structure — hub/bridge summary, capped node/edge preview — for the live run or a stored artifact. |
create_graph_artifact |
Estimates or builds a read-only spectral-sparsifier artifact from the current live run. Costly and opt-in; defaults to |
Cluster interpretation¶
Tool |
What It Does |
|---|---|
get_cluster_profile |
Targeted evidence for a single cluster from the cached dossier state. |
get_feature_signal |
Cross-cluster evidence for specific named features (numeric or categorical). |
get_cluster_signal_matrix |
Cross-cluster signal matrix ranked by discriminative power — which features actually separate the clusters. |
Export¶
Tool |
What It Does |
|---|---|
export_html_report |
Renders a full standalone HTML report from the cached dossier. Pass |
export_dataset_bundle |
Writes a Parquet bundle (raw/clean tabular data, graph nodes/edges/cosmic/groups) plus an |
Longitudinal and temporal panels¶
For entity × time data (patients over visits, sensors over readings). Requires create_config first for calibration.
Tool |
What It Does |
|---|---|
build_longitudinal_graph |
Pivots a long-format table into a panel and builds a |
diagnose_longitudinal_graph |
Measurements for whichever representation was built: trajectory similarity/cross-time stats, or the temporal tensor’s aggregation modes side by side. |
get_trajectory_archetypes |
Groups entities by the cluster-sequence they trace over time (trajectory surface only), with a threshold ladder. |
get_cross_time_neighbors |
Finds observations at other time steps resembling a given |
classify_trajectories |
Classifies entity trajectories into cohorts via complexity (Shannon entropy), transition (Markov self-retention), sequence (structural path type), Levenshtein, or DTW distance. |
Meta¶
Tool |
What It Does |
|---|---|
get_runtime_context |
Server cwd, cache directory, session state, and path-visibility guidance — useful for sandboxed clients that need to know what the server can actually see on disk. |
Example: Palmer Penguins¶
The Palmer Penguins dataset (344 birds, 3 species, 3 islands) is a useful benchmark because the correct answer is known. Running an unsupervised sweep—dropping species labels entirely—recovers the biology.
Getting the data
The dataset is not bundled with Pulsar. Export it to CSV with either of these one-liners:
# Option A: palmerpenguins package
# pip install palmerpenguins
import palmerpenguins
palmerpenguins.load_penguins().to_csv("demos/penguins/penguins.csv", index=False)
# Option B: seaborn (no extra install if already present)
import seaborn as sns
sns.load_dataset("penguins").to_csv("demos/penguins/penguins.csv", index=False)
run:
name: penguin_species_recovery_dim5
data: "demos/penguins/penguins.csv"
preprocessing:
drop_columns: ["species", "rowid", "year"]
encode:
island: {method: one_hot}
sex: {method: one_hot}
impute:
bill_length_mm: {method: fill_mean}
bill_depth_mm: {method: fill_mean}
flipper_length_mm: {method: fill_mean}
body_mass_g: {method: fill_mean}
sweep:
projection:
method: jl
dimensions:
values: [5]
seed:
values: [42]
center: true
ball_mapper:
epsilon:
range: {min: 0.80, max: 1.50, steps: 15}
cosmic_graph:
construction: minhash
construction_threshold: auto
The resulting graph shattered into components along island and sex boundaries, not just species—revealing that habitat and morphological sex are geometrically dominant. Chinstraps on Dream Island were structurally indistinguishable from Adelies on the same island: the math reflected the biology.
Bringing Your Own Data¶
Ensure your CSV is accessible on the machine running the MCP server.
Connect the server using the setup steps above.
Ask: “Look at
my_data.csvusing Pulsar. Are there hidden structural groups?”
The AI handles imputation, categorical encoding, and parameter scaling. Your job is to interpret the Dossier using domain knowledge.
See also
Configuration — full YAML schema reference