ds-mcp-server 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. ds_mcp_server-0.1.0/LICENSE +21 -0
  2. ds_mcp_server-0.1.0/PKG-INFO +211 -0
  3. ds_mcp_server-0.1.0/README.md +174 -0
  4. ds_mcp_server-0.1.0/pyproject.toml +47 -0
  5. ds_mcp_server-0.1.0/setup.cfg +4 -0
  6. ds_mcp_server-0.1.0/src/ds_mcp_server/__init__.py +2 -0
  7. ds_mcp_server-0.1.0/src/ds_mcp_server/_tools/__init__.py +0 -0
  8. ds_mcp_server-0.1.0/src/ds_mcp_server/_tools/plot_data.py +106 -0
  9. ds_mcp_server-0.1.0/src/ds_mcp_server/_tools/plot_interactive.py +419 -0
  10. ds_mcp_server-0.1.0/src/ds_mcp_server/_tools/plot_static.py +586 -0
  11. ds_mcp_server-0.1.0/src/ds_mcp_server/_tools/stats_analysis.py +272 -0
  12. ds_mcp_server-0.1.0/src/ds_mcp_server/_tools/system_tools.py +263 -0
  13. ds_mcp_server-0.1.0/src/ds_mcp_server/_tools/viz_config.py +325 -0
  14. ds_mcp_server-0.1.0/src/ds_mcp_server/_tools/viz_utils.py +235 -0
  15. ds_mcp_server-0.1.0/src/ds_mcp_server/_tools/web_tools.py +176 -0
  16. ds_mcp_server-0.1.0/src/ds_mcp_server/cli.py +78 -0
  17. ds_mcp_server-0.1.0/src/ds_mcp_server/client/__init__.py +0 -0
  18. ds_mcp_server-0.1.0/src/ds_mcp_server/client/_base.py +55 -0
  19. ds_mcp_server-0.1.0/src/ds_mcp_server/client/anthropic_client.py +100 -0
  20. ds_mcp_server-0.1.0/src/ds_mcp_server/client/openai_compat.py +114 -0
  21. ds_mcp_server-0.1.0/src/ds_mcp_server/server.py +482 -0
  22. ds_mcp_server-0.1.0/src/ds_mcp_server.egg-info/PKG-INFO +211 -0
  23. ds_mcp_server-0.1.0/src/ds_mcp_server.egg-info/SOURCES.txt +25 -0
  24. ds_mcp_server-0.1.0/src/ds_mcp_server.egg-info/dependency_links.txt +1 -0
  25. ds_mcp_server-0.1.0/src/ds_mcp_server.egg-info/entry_points.txt +3 -0
  26. ds_mcp_server-0.1.0/src/ds_mcp_server.egg-info/requires.txt +23 -0
  27. ds_mcp_server-0.1.0/src/ds_mcp_server.egg-info/top_level.txt +1 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 ds-mcp-server contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,211 @@
1
+ Metadata-Version: 2.4
2
+ Name: ds-mcp-server
3
+ Version: 0.1.0
4
+ Summary: An MCP server exposing data science tools (plotting, stats, data exploration) to any LLM client.
5
+ Author: Ahmad Alhineidi
6
+ License: MIT
7
+ Keywords: mcp,llm,data-science,visualization,plotly,pandas
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Topic :: Scientific/Engineering :: Visualization
12
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
13
+ Requires-Python: >=3.11
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Requires-Dist: mcp>=1.0.0
17
+ Requires-Dist: pandas>=2.0
18
+ Requires-Dist: plotly>=5.0
19
+ Requires-Dist: matplotlib>=3.7
20
+ Requires-Dist: seaborn>=0.13
21
+ Requires-Dist: numpy>=1.24
22
+ Requires-Dist: pingouin>=0.5
23
+ Requires-Dist: statsmodels>=0.14
24
+ Requires-Dist: wordcloud>=1.9
25
+ Requires-Dist: beautifulsoup4>=4.12
26
+ Requires-Dist: ddgs>=6.0
27
+ Requires-Dist: python-dotenv>=1.0
28
+ Requires-Dist: openai>=1.0
29
+ Provides-Extra: anthropic
30
+ Requires-Dist: anthropic>=0.20; extra == "anthropic"
31
+ Provides-Extra: playwright
32
+ Requires-Dist: playwright>=1.40; extra == "playwright"
33
+ Provides-Extra: all
34
+ Requires-Dist: anthropic>=0.20; extra == "all"
35
+ Requires-Dist: playwright>=1.40; extra == "all"
36
+ Dynamic: license-file
37
+
38
+ # ds-mcp-server
39
+
40
+ `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.
41
+
42
+ ## Installation
43
+
44
+ Future PyPI install:
45
+
46
+ ```bash
47
+ pip install ds-mcp-server
48
+ ```
49
+
50
+ Local development install:
51
+
52
+ ```bash
53
+ pip install -e .
54
+ ```
55
+
56
+ Optional extras:
57
+
58
+ ```bash
59
+ pip install -e ".[anthropic]"
60
+ pip install -e ".[playwright]"
61
+ pip install -e ".[all]"
62
+ ```
63
+
64
+ ## Quick start
65
+
66
+ 1. Copy `.env.example` to `.env`.
67
+ 2. Fill in your provider settings.
68
+ 3. Install the package.
69
+ 4. Start either the MCP server or the interactive client.
70
+
71
+ ### OpenAI
72
+
73
+ ```bash
74
+ export PROVIDER=openai
75
+ export API_KEY=sk-...
76
+ export MODEL=gpt-4o
77
+ ds-mcp-client
78
+ ```
79
+
80
+ ### Claude / Anthropic
81
+
82
+ ```bash
83
+ export PROVIDER=anthropic
84
+ export ANTHROPIC_API_KEY=sk-ant-...
85
+ export MODEL=claude-opus-4-5
86
+ ds-mcp-client
87
+ ```
88
+
89
+ ### Gemini (OpenAI-compatible endpoint)
90
+
91
+ ```bash
92
+ export PROVIDER=gemini
93
+ export API_KEY=AIza...
94
+ export MODEL=gemini-2.0-flash
95
+ ds-mcp-client
96
+ ```
97
+
98
+ ### Ollama
99
+
100
+ ```bash
101
+ export PROVIDER=ollama
102
+ export API_BASE_URL=http://localhost:11434/v1
103
+ export MODEL=llama3
104
+ ds-mcp-client
105
+ ```
106
+
107
+ ### GPUStack / LM Studio / other OpenAI-compatible servers
108
+
109
+ ```bash
110
+ export PROVIDER=openai-compat
111
+ export API_BASE_URL=https://your-endpoint.example/v1
112
+ export API_KEY=your-key
113
+ export MODEL=your-model
114
+ ds-mcp-client
115
+ ```
116
+
117
+ ## Running the MCP server
118
+
119
+ ```bash
120
+ ds-mcp-server
121
+ ```
122
+
123
+ ## Claude Desktop MCP config
124
+
125
+ Add the server to your Claude Desktop MCP configuration:
126
+
127
+ ```json
128
+ {
129
+ "mcpServers": {
130
+ "ds-mcp-server": {
131
+ "command": "ds-mcp-server",
132
+ "args": []
133
+ }
134
+ }
135
+ }
136
+ ```
137
+
138
+ ## Environment variables
139
+
140
+ | Variable | Required | Description |
141
+ | --- | --- | --- |
142
+ | `PROVIDER` | No | One of `openai`, `anthropic`, `gemini`, `ollama`, `openai-compat`. |
143
+ | `API_KEY` | Usually | Generic API key used by OpenAI-compatible providers and as a fallback for Anthropic. |
144
+ | `ANTHROPIC_API_KEY` | Anthropic only | Preferred Anthropic key. |
145
+ | `API_BASE_URL` | Sometimes | Required for `openai-compat`; optional override for Ollama, Gemini, or self-hosted endpoints. |
146
+ | `MODEL` | No | Model override. Defaults are provider-specific. |
147
+
148
+ ## Available tools
149
+
150
+ ### Interactive plots
151
+
152
+ - `plot_interactive_histogram`
153
+ - `plot_interactive_scatterplot`
154
+ - `plot_interactive_boxplot`
155
+ - `plot_interactive_lineplot`
156
+ - `plot_interactive_barchart`
157
+ - `plot_interactive_scatter_matrix`
158
+ - `plot_interactive_correlation_heatmap`
159
+ - `generate_custom_plotly`
160
+ - `get_all_columns_summary`
161
+ - `get_column_summary`
162
+
163
+ ### Static plots
164
+
165
+ - `plot_static_histogram`
166
+ - `plot_static_scatterplot`
167
+ - `plot_static_boxplot`
168
+ - `plot_static_lineplot`
169
+ - `plot_static_barchart`
170
+ - `plot_static_pairplot`
171
+ - `plot_static_correlation_heatmap`
172
+ - `plot_static_wordcloud`
173
+ - `generate_custom_static_plot`
174
+
175
+ ### Statistical analysis
176
+
177
+ - `run_correlation`
178
+ - `run_group_comparison`
179
+ - `run_linear_regression`
180
+ - `rank_target_correlations`
181
+
182
+ ### System tools
183
+
184
+ - `run_shell_command`
185
+ - `read_file`
186
+ - `write_file`
187
+ - `patch_file`
188
+ - `list_directory`
189
+ - `find_in_files`
190
+ - `run_background_process`
191
+ - `stop_background_process`
192
+ - `list_background_processes`
193
+ - `http_request`
194
+
195
+ ### Web tools
196
+
197
+ - `search_web`
198
+ - `fetch_webpage`
199
+ - `screenshot_webpage`
200
+
201
+ ## Requirements
202
+
203
+ - Python 3.11+
204
+ - `mcp`
205
+ - `pandas`, `numpy`
206
+ - `plotly`, `matplotlib`, `seaborn`, `wordcloud`
207
+ - `pingouin`, `statsmodels`
208
+ - `beautifulsoup4`, `ddgs`
209
+ - `openai`
210
+ - `anthropic` (optional)
211
+ - `playwright` (optional, for screenshots)
@@ -0,0 +1,174 @@
1
+ # ds-mcp-server
2
+
3
+ `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.
4
+
5
+ ## Installation
6
+
7
+ Future PyPI install:
8
+
9
+ ```bash
10
+ pip install ds-mcp-server
11
+ ```
12
+
13
+ Local development install:
14
+
15
+ ```bash
16
+ pip install -e .
17
+ ```
18
+
19
+ Optional extras:
20
+
21
+ ```bash
22
+ pip install -e ".[anthropic]"
23
+ pip install -e ".[playwright]"
24
+ pip install -e ".[all]"
25
+ ```
26
+
27
+ ## Quick start
28
+
29
+ 1. Copy `.env.example` to `.env`.
30
+ 2. Fill in your provider settings.
31
+ 3. Install the package.
32
+ 4. Start either the MCP server or the interactive client.
33
+
34
+ ### OpenAI
35
+
36
+ ```bash
37
+ export PROVIDER=openai
38
+ export API_KEY=sk-...
39
+ export MODEL=gpt-4o
40
+ ds-mcp-client
41
+ ```
42
+
43
+ ### Claude / Anthropic
44
+
45
+ ```bash
46
+ export PROVIDER=anthropic
47
+ export ANTHROPIC_API_KEY=sk-ant-...
48
+ export MODEL=claude-opus-4-5
49
+ ds-mcp-client
50
+ ```
51
+
52
+ ### Gemini (OpenAI-compatible endpoint)
53
+
54
+ ```bash
55
+ export PROVIDER=gemini
56
+ export API_KEY=AIza...
57
+ export MODEL=gemini-2.0-flash
58
+ ds-mcp-client
59
+ ```
60
+
61
+ ### Ollama
62
+
63
+ ```bash
64
+ export PROVIDER=ollama
65
+ export API_BASE_URL=http://localhost:11434/v1
66
+ export MODEL=llama3
67
+ ds-mcp-client
68
+ ```
69
+
70
+ ### GPUStack / LM Studio / other OpenAI-compatible servers
71
+
72
+ ```bash
73
+ export PROVIDER=openai-compat
74
+ export API_BASE_URL=https://your-endpoint.example/v1
75
+ export API_KEY=your-key
76
+ export MODEL=your-model
77
+ ds-mcp-client
78
+ ```
79
+
80
+ ## Running the MCP server
81
+
82
+ ```bash
83
+ ds-mcp-server
84
+ ```
85
+
86
+ ## Claude Desktop MCP config
87
+
88
+ Add the server to your Claude Desktop MCP configuration:
89
+
90
+ ```json
91
+ {
92
+ "mcpServers": {
93
+ "ds-mcp-server": {
94
+ "command": "ds-mcp-server",
95
+ "args": []
96
+ }
97
+ }
98
+ }
99
+ ```
100
+
101
+ ## Environment variables
102
+
103
+ | Variable | Required | Description |
104
+ | --- | --- | --- |
105
+ | `PROVIDER` | No | One of `openai`, `anthropic`, `gemini`, `ollama`, `openai-compat`. |
106
+ | `API_KEY` | Usually | Generic API key used by OpenAI-compatible providers and as a fallback for Anthropic. |
107
+ | `ANTHROPIC_API_KEY` | Anthropic only | Preferred Anthropic key. |
108
+ | `API_BASE_URL` | Sometimes | Required for `openai-compat`; optional override for Ollama, Gemini, or self-hosted endpoints. |
109
+ | `MODEL` | No | Model override. Defaults are provider-specific. |
110
+
111
+ ## Available tools
112
+
113
+ ### Interactive plots
114
+
115
+ - `plot_interactive_histogram`
116
+ - `plot_interactive_scatterplot`
117
+ - `plot_interactive_boxplot`
118
+ - `plot_interactive_lineplot`
119
+ - `plot_interactive_barchart`
120
+ - `plot_interactive_scatter_matrix`
121
+ - `plot_interactive_correlation_heatmap`
122
+ - `generate_custom_plotly`
123
+ - `get_all_columns_summary`
124
+ - `get_column_summary`
125
+
126
+ ### Static plots
127
+
128
+ - `plot_static_histogram`
129
+ - `plot_static_scatterplot`
130
+ - `plot_static_boxplot`
131
+ - `plot_static_lineplot`
132
+ - `plot_static_barchart`
133
+ - `plot_static_pairplot`
134
+ - `plot_static_correlation_heatmap`
135
+ - `plot_static_wordcloud`
136
+ - `generate_custom_static_plot`
137
+
138
+ ### Statistical analysis
139
+
140
+ - `run_correlation`
141
+ - `run_group_comparison`
142
+ - `run_linear_regression`
143
+ - `rank_target_correlations`
144
+
145
+ ### System tools
146
+
147
+ - `run_shell_command`
148
+ - `read_file`
149
+ - `write_file`
150
+ - `patch_file`
151
+ - `list_directory`
152
+ - `find_in_files`
153
+ - `run_background_process`
154
+ - `stop_background_process`
155
+ - `list_background_processes`
156
+ - `http_request`
157
+
158
+ ### Web tools
159
+
160
+ - `search_web`
161
+ - `fetch_webpage`
162
+ - `screenshot_webpage`
163
+
164
+ ## Requirements
165
+
166
+ - Python 3.11+
167
+ - `mcp`
168
+ - `pandas`, `numpy`
169
+ - `plotly`, `matplotlib`, `seaborn`, `wordcloud`
170
+ - `pingouin`, `statsmodels`
171
+ - `beautifulsoup4`, `ddgs`
172
+ - `openai`
173
+ - `anthropic` (optional)
174
+ - `playwright` (optional, for screenshots)
@@ -0,0 +1,47 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta:__legacy__"
4
+
5
+ [project]
6
+ name = "ds-mcp-server"
7
+ version = "0.1.0"
8
+ description = "An MCP server exposing data science tools (plotting, stats, data exploration) to any LLM client."
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ requires-python = ">=3.11"
12
+ authors = [{ name = "Ahmad Alhineidi" }]
13
+ keywords = ["mcp", "llm", "data-science", "visualization", "plotly", "pandas"]
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ "Topic :: Scientific/Engineering :: Visualization",
19
+ "Topic :: Scientific/Engineering :: Artificial Intelligence",
20
+ ]
21
+ dependencies = [
22
+ "mcp>=1.0.0",
23
+ "pandas>=2.0",
24
+ "plotly>=5.0",
25
+ "matplotlib>=3.7",
26
+ "seaborn>=0.13",
27
+ "numpy>=1.24",
28
+ "pingouin>=0.5",
29
+ "statsmodels>=0.14",
30
+ "wordcloud>=1.9",
31
+ "beautifulsoup4>=4.12",
32
+ "ddgs>=6.0",
33
+ "python-dotenv>=1.0",
34
+ "openai>=1.0",
35
+ ]
36
+
37
+ [project.optional-dependencies]
38
+ anthropic = ["anthropic>=0.20"]
39
+ playwright = ["playwright>=1.40"]
40
+ all = ["anthropic>=0.20", "playwright>=1.40"]
41
+
42
+ [project.scripts]
43
+ ds-mcp-server = "ds_mcp_server.cli:serve"
44
+ ds-mcp-client = "ds_mcp_server.cli:chat"
45
+
46
+ [tool.setuptools.packages.find]
47
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,2 @@
1
+ """ds-mcp-server — Data Science MCP Server and multi-provider client."""
2
+ __version__ = "0.1.0"
@@ -0,0 +1,106 @@
1
+ """
2
+ Data Exploration Module for the AI Visualization Engine.
3
+ Provides tools for the LLM to inspect dataset columns before plotting.
4
+ """
5
+
6
+ import pandas as pd
7
+
8
+ from .viz_config import MAX_ROWS
9
+ from .viz_utils import load_data_safely, was_last_load_truncated
10
+
11
+
12
+ def get_column_summary_impl(data_file_path: str, column: str) -> str:
13
+ """
14
+ Analyzes a specific column in the dataset and returns a statistical summary.
15
+
16
+ For numeric columns, it calculates the minimum, maximum, mean, and null count.
17
+ For categorical columns, it calculates the number of unique values, lists
18
+ the top 10 unique values, and the null count.
19
+
20
+ Args:
21
+ data_file_path: The absolute path to the data file.
22
+ column: The name of the column to analyze.
23
+
24
+ Returns:
25
+ A formatted string containing the column statistics, or an error message
26
+ if the column cannot be found or analyzed.
27
+ """
28
+ try:
29
+ df = load_data_safely(data_file_path)
30
+
31
+ truncation_note = ""
32
+ if was_last_load_truncated(data_file_path):
33
+ truncation_note = (
34
+ f"\n\nNote: dataset was truncated to the first {MAX_ROWS:,} rows for "
35
+ "memory safety. Mention this in your final summary."
36
+ )
37
+
38
+ if column not in df.columns:
39
+ return f"Error: Column '{column}' not found in the dataset."
40
+
41
+ col_data = df[column]
42
+ null_count = col_data.isna().sum()
43
+
44
+ if pd.api.types.is_numeric_dtype(col_data):
45
+ min_val = col_data.min()
46
+ max_val = col_data.max()
47
+ mean_val = col_data.mean()
48
+
49
+ return (
50
+ f"Numeric Column '{column}': Min={min_val}, Max={max_val}, "
51
+ f"Mean={mean_val:.2f}, Nulls={null_count}{truncation_note}"
52
+ )
53
+ else:
54
+ unique_vals = col_data.unique()
55
+ total_unique = len(unique_vals)
56
+
57
+ if total_unique > 10:
58
+ top_vals = ", ".join(map(str, unique_vals[:10]))
59
+ val_str = f"{top_vals}... (+ {total_unique - 10} more)"
60
+ else:
61
+ val_str = ", ".join(map(str, unique_vals))
62
+
63
+ return (
64
+ f"Categorical Column '{column}': {total_unique} unique values. "
65
+ f"Top values: {val_str}. Nulls={null_count}{truncation_note}"
66
+ )
67
+
68
+ except Exception as e:
69
+ return f"Error analyzing column '{column}': {str(e)}"
70
+
71
+
72
+ def get_all_columns_summary_impl(data_file_path: str) -> str:
73
+ """
74
+ Returns a compact schema of every column: name and type only.
75
+ Intentionally terse to minimise token load on the model.
76
+ Use get_column_summary for detailed stats on a specific column.
77
+ """
78
+ try:
79
+ df = load_data_safely(data_file_path)
80
+
81
+ truncation_note = ""
82
+ if was_last_load_truncated(data_file_path):
83
+ truncation_note = f" (truncated to {MAX_ROWS:,} rows)"
84
+
85
+ numeric_cols = [c for c in df.columns if pd.api.types.is_numeric_dtype(df[c])]
86
+ datetime_cols = [c for c in df.columns if pd.api.types.is_datetime64_any_dtype(df[c])]
87
+ categorical_cols = [c for c in df.columns if c not in numeric_cols and c not in datetime_cols]
88
+
89
+ lines = [
90
+ f"Dataset: {len(df):,} rows × {len(df.columns)} columns{truncation_note}",
91
+ f"Numeric columns ({len(numeric_cols)}): {', '.join(numeric_cols)}",
92
+ ]
93
+ if categorical_cols:
94
+ cat_details = []
95
+ for c in categorical_cols:
96
+ unique_vals = df[c].dropna().unique()
97
+ sample = ", ".join(str(v) for v in sorted(unique_vals, key=str)[:5])
98
+ cat_details.append(f"{c} [{sample}]")
99
+ lines.append(f"Categorical columns ({len(categorical_cols)}): {'; '.join(cat_details)}")
100
+ if datetime_cols:
101
+ lines.append(f"Datetime columns ({len(datetime_cols)}): {', '.join(datetime_cols)}")
102
+
103
+ return "\n".join(lines)
104
+
105
+ except Exception as e:
106
+ return f"Error summarizing columns: {str(e)}"