An MCP server exposing data science tools (plotting, stats, data exploration) to any LLM client.
Project description
ds-mcp-server
ds-mcp-server packages a FastMCP server with data science, plotting, statistics, system, and web tools, plus interactive CLI clients for OpenAI-compatible providers and Anthropic Claude.
Installation
Install from PyPI:
pip install ds-mcp-server
Local development install:
pip install -e .
Optional extras:
pip install -e ".[anthropic]"
pip install -e ".[playwright]"
pip install -e ".[all]"
Quick start
- Copy
.env.exampleto.env. - Fill in your provider settings.
- Install the package.
- Start either the MCP server or the interactive client.
OpenAI
export PROVIDER=openai
export API_KEY=sk-...
export MODEL=gpt-4o
ds-mcp-client
Claude / Anthropic
export PROVIDER=anthropic
export ANTHROPIC_API_KEY=sk-ant-...
export MODEL=claude-opus-4-5
ds-mcp-client
Gemini (OpenAI-compatible endpoint)
export PROVIDER=gemini
export API_KEY=AIza...
export MODEL=gemini-2.0-flash
ds-mcp-client
Ollama
export PROVIDER=ollama
export API_BASE_URL=http://localhost:11434/v1
export MODEL=llama3
ds-mcp-client
GPUStack / LM Studio / other OpenAI-compatible servers
export PROVIDER=openai-compat
export API_BASE_URL=https://your-endpoint.example/v1
export API_KEY=your-key
export MODEL=your-model
ds-mcp-client
Running the MCP server
ds-mcp-server
To also expose the optional (dangerous) system tools — shell execution, file read/write/patch, background processes, and HTTP requests:
ds-mcp-server --enable-system-tools
# or, equivalently:
DS_MCP_ENABLE_SYSTEM_TOOLS=1 ds-mcp-server
See the Optional system tools section below before enabling.
⚠️ Optional system tools
By default ds-mcp-server only exposes safe read-only data-science tools
(plots, statistics, dataset summaries, web fetch/search). A second group of
system / coder tools is bundled in the package but is disabled by default
because it grants the connected LLM effectively remote-code-execution power.
The gated tools are:
run_shell_command— runs any shell command with your user's privilegesread_file,write_file,patch_file,list_directory— arbitrary file I/Ofind_in_files— regex-search anywhere on diskrun_background_process,stop_background_process,list_background_processeshttp_request— arbitrary outbound HTTP (SSRF risk: can reach localhost, cloud metadata endpoints, internal services, etc.)
Enabling
Only enable inside a sandbox you trust (Docker container, WSL, dedicated VM, or a throwaway user account). The LLM decides when to call these — a single prompt-injection or misinterpretation is enough to trigger destructive actions.
Two equivalent ways to enable:
# Preferred: env var, works with any MCP client (Claude Desktop, LM Studio, …)
export DS_MCP_ENABLE_SYSTEM_TOOLS=1
# Or as a CLI flag when launching the server directly
ds-mcp-server --enable-system-tools
When enabled, the server prints a warning banner to stderr at startup listing every dangerous tool that was registered. When disabled, it prints a one-line hint telling you how to opt in.
Claude Desktop config with system tools enabled
{
"mcpServers": {
"ds-mcp-server": {
"command": "ds-mcp-server",
"args": ["--enable-system-tools"]
}
}
}
🔒 Sandbox for LLM-generated plotting code
Two tools — generate_custom_plotly and generate_custom_static_plot — accept
a Python code string produced by the LLM and exec() it in-process to render a
plot. Because that code can be influenced by any dataset, webpage, or file the
model reads, ds-mcp-server sandboxes it by default.
What the sandbox blocks
importandfrom ... importstatements (all needed libraries —pd,np,px,go,plt,sns,WordCloud,df— are pre-injected).- Calls to
eval,exec,compile,open,__import__,getattr,setattr,delattr,globals,locals,vars,input,breakpoint. - Access to any dunder attribute (
.__class__,.__subclasses__, etc.) — this closes the common().__class__.__mro__[-1].__subclasses__()escape. - Runaway execution — a 60s wall-clock timeout aborts the tool call.
What the sandbox does NOT block (honest limits)
- Filesystem access via pre-imported libraries.
pd.read_csv("/etc/passwd")still works because pandas legitimately needs to read files. For strong isolation run the server inside a container, VM, or dedicated user account. - Native-code CPU/memory exhaustion. Python threads cannot interrupt C extensions, so the timeout is best-effort against numpy/pandas hot loops.
Disabling the sandbox
If you trust the LLM and want unrestricted exec (e.g. for advanced plotting
that legitimately needs import), you can opt out:
# Env var (works with any MCP client)
export DS_MCP_ALLOW_UNRESTRICTED_EXEC=1
# Or CLI flag
ds-mcp-server --allow-unrestricted-exec
When disabled, the server prints a warning banner to stderr at startup.
Claude Desktop MCP config
Add the server to your Claude Desktop MCP configuration:
🖥️ Browser chat UI (optional)
Prefer clicking over typing? ds-mcp-server ships with an optional
browser-based chat UI that talks to the same MCP server and renders plots
inline (interactive Plotly HTML in an iframe, PNG/SVG as images).
Install the extra:
pip install 'ds-mcp-server[web]'
Launch it (with your .env in the current directory or in ~/.env):
ds-mcp-webui # http://127.0.0.1:8765
ds-mcp-webui --port 9000 # custom port
ds-mcp-webui -p openai -m gpt-4o
Then open the printed URL in your browser. The UI:
- Streams tool calls as they happen (little pill chips per tool).
- Renders generated plots inline — interactive Plotly plots are fully scrollable/zoomable directly in the chat.
- Shows all available MCP tools in a searchable sidebar.
- Works with any provider the CLI client supports (OpenAI, Anthropic, Gemini, Ollama, LM Studio / GPUStack / any OpenAI-compat endpoint).
- Settings panel (⚙ in the sidebar) lets you toggle the dangerous
opt-ins — System / coder tools and Unrestricted
exec()— with clear warnings. Toggling either one restarts the underlying MCP process so the change takes effect without leaving the browser.
By default it binds to 127.0.0.1 (localhost only). Use --host 0.0.0.0
to expose it on your LAN — but be aware that anyone reaching the port can
chat through your API key.
{
"mcpServers": {
"ds-mcp-server": {
"command": "ds-mcp-server",
"args": []
}
}
}
Environment variables
| Variable | Required | Description |
|---|---|---|
PROVIDER |
No | One of openai, anthropic, gemini, ollama, openai-compat. |
API_KEY |
Usually | Generic API key used by OpenAI-compatible providers and as a fallback for Anthropic. |
ANTHROPIC_API_KEY |
Anthropic only | Preferred Anthropic key. |
API_BASE_URL |
Sometimes | Required for openai-compat; optional override for Ollama, Gemini, or self-hosted endpoints. |
MODEL |
No | Model override. Defaults are provider-specific. |
Available tools
Interactive plots
plot_interactive_histogramplot_interactive_scatterplotplot_interactive_boxplotplot_interactive_lineplotplot_interactive_barchartplot_interactive_scatter_matrixplot_interactive_correlation_heatmapgenerate_custom_plotlyget_all_columns_summaryget_column_summary
Static plots
plot_static_histogramplot_static_scatterplotplot_static_boxplotplot_static_lineplotplot_static_barchartplot_static_pairplotplot_static_correlation_heatmapplot_static_wordcloudgenerate_custom_static_plot
Statistical analysis
run_correlationrun_group_comparisonrun_linear_regressionrank_target_correlations
System tools (opt-in — see Optional system tools)
Only registered when DS_MCP_ENABLE_SYSTEM_TOOLS=1 (or --enable-system-tools).
run_shell_commandread_filewrite_filepatch_filelist_directoryfind_in_filesrun_background_processstop_background_processlist_background_processeshttp_request
Web tools
search_webfetch_webpagescreenshot_webpage
Requirements
- Python 3.11+
mcppandas,numpyplotly,matplotlib,seaborn,wordcloudpingouin,statsmodelsbeautifulsoup4,ddgsopenaianthropic(optional)playwright(optional, for screenshots)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ds_mcp_server-0.2.0.tar.gz.
File metadata
- Download URL: ds_mcp_server-0.2.0.tar.gz
- Upload date:
- Size: 79.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
daaad84aad09cb66a1d7eac4cd1d8ff465ff0de74d6d64743c3d0403ae974a94
|
|
| MD5 |
9049da0f4393046d916216465215366a
|
|
| BLAKE2b-256 |
ccb7c9fd554187be78672a8665d446aa865335b1f77b4e09d31af2084f9b744e
|
Provenance
The following attestation bundles were made for ds_mcp_server-0.2.0.tar.gz:
Publisher:
publish.yml on ahmad-zurih/ds-mcp-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ds_mcp_server-0.2.0.tar.gz -
Subject digest:
daaad84aad09cb66a1d7eac4cd1d8ff465ff0de74d6d64743c3d0403ae974a94 - Sigstore transparency entry: 2212276765
- Sigstore integration time:
-
Permalink:
ahmad-zurih/ds-mcp-server@9fe5ef9f49afb1f7af8aa4bb12e095785cffd64c -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/ahmad-zurih
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9fe5ef9f49afb1f7af8aa4bb12e095785cffd64c -
Trigger Event:
push
-
Statement type:
File details
Details for the file ds_mcp_server-0.2.0-py3-none-any.whl.
File metadata
- Download URL: ds_mcp_server-0.2.0-py3-none-any.whl
- Upload date:
- Size: 70.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
12365dcc9d467eb2fec822741f496d0dd0c8c55e2ea7955771f36e87f1d790d2
|
|
| MD5 |
b3e22c765807f6385b13d4e6e4f50a30
|
|
| BLAKE2b-256 |
f167a4beb1c1f164a16b43d3bc39d88a080cde9f213249a8bb354d6bb3698892
|
Provenance
The following attestation bundles were made for ds_mcp_server-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on ahmad-zurih/ds-mcp-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ds_mcp_server-0.2.0-py3-none-any.whl -
Subject digest:
12365dcc9d467eb2fec822741f496d0dd0c8c55e2ea7955771f36e87f1d790d2 - Sigstore transparency entry: 2212276782
- Sigstore integration time:
-
Permalink:
ahmad-zurih/ds-mcp-server@9fe5ef9f49afb1f7af8aa4bb12e095785cffd64c -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/ahmad-zurih
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@9fe5ef9f49afb1f7af8aa4bb12e095785cffd64c -
Trigger Event:
push
-
Statement type: