stats-compass-mcp 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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Olatunji Ogunbiyi
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,187 @@
1
+ Metadata-Version: 2.3
2
+ Name: stats-compass-mcp
3
+ Version: 0.1.0
4
+ Summary: MCP server exposing stats-compass-core tools to LLMs like ChatGPT, Claude, and Gemini
5
+ License: MIT
6
+ Keywords: mcp,llm,data-science,pandas,ai-agents,chatgpt,claude
7
+ Author: Olatunji Ogunbiyi
8
+ Author-email: oogunbiyi21@users.noreply.github.com
9
+ Requires-Python: >=3.11,<4.0
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Scientific/Engineering
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Requires-Dist: mcp (>=1.0.0,<2.0.0)
21
+ Requires-Dist: stats-compass-core[all] (>=0.1.3,<0.2.0)
22
+ Description-Content-Type: text/markdown
23
+
24
+ # stats-compass-mcp
25
+
26
+ MCP server that exposes [stats-compass-core](https://pypi.org/project/stats-compass-core/) tools to LLMs like ChatGPT, Claude, and Gemini.
27
+
28
+ ## What is this?
29
+
30
+ This package turns the `stats-compass-core` toolkit into an MCP (Model Context Protocol) server. Once running, any MCP-compatible client (ChatGPT, Claude, Cursor, VS Code, etc.) can use your data analysis tools directly.
31
+
32
+ ## Installation
33
+
34
+ ```bash
35
+ pip install stats-compass-mcp
36
+ ```
37
+
38
+ ## Quick Start
39
+
40
+ ### Start the server
41
+
42
+ ```bash
43
+ stats-compass-mcp serve
44
+ ```
45
+
46
+ ### Configure your MCP client
47
+
48
+ #### For Claude Desktop (Recommended)
49
+
50
+ The easiest way to run this server is using `uvx` (part of the [uv](https://github.com/astral-sh/uv) toolkit), which downloads and runs the server in an isolated environment without installation.
51
+
52
+ Add this to your `claude_desktop_config.json`:
53
+
54
+ ```json
55
+ {
56
+ "mcpServers": {
57
+ "stats-compass": {
58
+ "command": "uvx",
59
+ "args": ["stats-compass-mcp", "serve"]
60
+ }
61
+ }
62
+ }
63
+ ```
64
+
65
+ #### Manual Installation
66
+
67
+ If you prefer to install it globally:
68
+
69
+ ```bash
70
+ pip install stats-compass-mcp
71
+ ```
72
+
73
+ Then configure your client:
74
+
75
+ ```json
76
+ {
77
+ "mcpServers": {
78
+ "stats-compass": {
79
+ "command": "stats-compass-mcp",
80
+ "args": ["serve"]
81
+ }
82
+ }
83
+ }
84
+ ```
85
+
86
+ ## Available Tools
87
+
88
+ Once connected, the following tools are available to LLMs:
89
+
90
+ ### Data Loading & Management
91
+ - `load_csv` - Load CSV files into state
92
+ - `load_dataset` - Load built-in sample datasets
93
+ - `list_dataframes` - List all DataFrames in state
94
+ - `get_schema` - Get column types and info
95
+ - `get_sample` - Preview rows from a DataFrame
96
+
97
+ ### Data Cleaning
98
+ - `dropna` - Remove missing values
99
+ - `apply_imputation` - Fill missing values
100
+ - `dedupe` - Remove duplicate rows
101
+ - `handle_outliers` - Detect and handle outliers
102
+
103
+ ### Transforms
104
+ - `filter_dataframe` - Filter rows by condition
105
+ - `groupby_aggregate` - Group and aggregate data
106
+ - `pivot` - Pivot tables
107
+ - `add_column` - Add calculated columns
108
+ - `rename_columns` - Rename columns
109
+ - `drop_columns` - Remove columns
110
+
111
+ ### EDA & Statistics
112
+ - `describe` - Summary statistics
113
+ - `correlations` - Correlation matrix
114
+ - `hypothesis_tests` - T-tests, chi-square, etc.
115
+ - `data_quality` - Data quality report
116
+
117
+ ### Visualization
118
+ - `histogram` - Distribution plots
119
+ - `scatter_plot` - Scatter plots
120
+ - `bar_chart` - Bar charts
121
+ - `lineplot` - Line plots
122
+
123
+ ### Machine Learning
124
+ - `train_linear_regression` - Linear regression
125
+ - `train_logistic_regression` - Logistic regression
126
+ - `train_random_forest_classifier` - Random forest classification
127
+ - `train_random_forest_regressor` - Random forest regression
128
+ - `evaluate_model` - Model evaluation metrics
129
+
130
+ ### Time Series (ARIMA)
131
+ - `check_stationarity` - ADF/KPSS tests
132
+ - `fit_arima` - Fit ARIMA models
133
+ - `forecast_arima` - Generate forecasts
134
+ - `find_optimal_arima` - Auto parameter search
135
+
136
+ ## How It Works
137
+
138
+ ```
139
+ ┌─────────────────────────────────────────────────────────────┐
140
+ │ MCP Client │
141
+ │ (ChatGPT, Claude, Cursor, VS Code) │
142
+ └─────────────────────────┬───────────────────────────────────┘
143
+ │ MCP Protocol
144
+
145
+ ┌─────────────────────────────────────────────────────────────┐
146
+ │ stats-compass-mcp │
147
+ │ ┌─────────────────────────────────────────────────────┐ │
148
+ │ │ MCP Server (this package) │ │
149
+ │ │ • Registers tools from stats-compass-core │ │
150
+ │ │ • Manages DataFrameState per session │ │
151
+ │ │ • Converts tool results to MCP responses │ │
152
+ │ └─────────────────────────────────────────────────────┘ │
153
+ │ │ │
154
+ │ ▼ │
155
+ │ ┌─────────────────────────────────────────────────────┐ │
156
+ │ │ stats-compass-core (PyPI) │ │
157
+ │ │ • DataFrameState (server-side state) │ │
158
+ │ │ • 40+ deterministic tools │ │
159
+ │ │ • Pydantic schemas for all inputs/outputs │ │
160
+ │ └─────────────────────────────────────────────────────┘ │
161
+ └─────────────────────────────────────────────────────────────┘
162
+ ```
163
+
164
+ ## Development
165
+
166
+ ```bash
167
+ # Clone and install
168
+ git clone https://github.com/oogunbiyi21/stats-compass-mcp.git
169
+ cd stats-compass-mcp
170
+ poetry install
171
+
172
+ # Run tests
173
+ poetry run pytest
174
+
175
+ # Run the server locally
176
+ poetry run stats-compass-mcp serve
177
+ ```
178
+
179
+ ## Related Projects
180
+
181
+ - [stats-compass-core](https://github.com/oogunbiyi21/stats-compass-core) - The underlying toolkit
182
+ - [stats-compass](https://github.com/oogunbiyi21/stats-compass) - Streamlit chat UI for data analysis
183
+
184
+ ## License
185
+
186
+ MIT
187
+
@@ -0,0 +1,163 @@
1
+ # stats-compass-mcp
2
+
3
+ MCP server that exposes [stats-compass-core](https://pypi.org/project/stats-compass-core/) tools to LLMs like ChatGPT, Claude, and Gemini.
4
+
5
+ ## What is this?
6
+
7
+ This package turns the `stats-compass-core` toolkit into an MCP (Model Context Protocol) server. Once running, any MCP-compatible client (ChatGPT, Claude, Cursor, VS Code, etc.) can use your data analysis tools directly.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ pip install stats-compass-mcp
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ### Start the server
18
+
19
+ ```bash
20
+ stats-compass-mcp serve
21
+ ```
22
+
23
+ ### Configure your MCP client
24
+
25
+ #### For Claude Desktop (Recommended)
26
+
27
+ The easiest way to run this server is using `uvx` (part of the [uv](https://github.com/astral-sh/uv) toolkit), which downloads and runs the server in an isolated environment without installation.
28
+
29
+ Add this to your `claude_desktop_config.json`:
30
+
31
+ ```json
32
+ {
33
+ "mcpServers": {
34
+ "stats-compass": {
35
+ "command": "uvx",
36
+ "args": ["stats-compass-mcp", "serve"]
37
+ }
38
+ }
39
+ }
40
+ ```
41
+
42
+ #### Manual Installation
43
+
44
+ If you prefer to install it globally:
45
+
46
+ ```bash
47
+ pip install stats-compass-mcp
48
+ ```
49
+
50
+ Then configure your client:
51
+
52
+ ```json
53
+ {
54
+ "mcpServers": {
55
+ "stats-compass": {
56
+ "command": "stats-compass-mcp",
57
+ "args": ["serve"]
58
+ }
59
+ }
60
+ }
61
+ ```
62
+
63
+ ## Available Tools
64
+
65
+ Once connected, the following tools are available to LLMs:
66
+
67
+ ### Data Loading & Management
68
+ - `load_csv` - Load CSV files into state
69
+ - `load_dataset` - Load built-in sample datasets
70
+ - `list_dataframes` - List all DataFrames in state
71
+ - `get_schema` - Get column types and info
72
+ - `get_sample` - Preview rows from a DataFrame
73
+
74
+ ### Data Cleaning
75
+ - `dropna` - Remove missing values
76
+ - `apply_imputation` - Fill missing values
77
+ - `dedupe` - Remove duplicate rows
78
+ - `handle_outliers` - Detect and handle outliers
79
+
80
+ ### Transforms
81
+ - `filter_dataframe` - Filter rows by condition
82
+ - `groupby_aggregate` - Group and aggregate data
83
+ - `pivot` - Pivot tables
84
+ - `add_column` - Add calculated columns
85
+ - `rename_columns` - Rename columns
86
+ - `drop_columns` - Remove columns
87
+
88
+ ### EDA & Statistics
89
+ - `describe` - Summary statistics
90
+ - `correlations` - Correlation matrix
91
+ - `hypothesis_tests` - T-tests, chi-square, etc.
92
+ - `data_quality` - Data quality report
93
+
94
+ ### Visualization
95
+ - `histogram` - Distribution plots
96
+ - `scatter_plot` - Scatter plots
97
+ - `bar_chart` - Bar charts
98
+ - `lineplot` - Line plots
99
+
100
+ ### Machine Learning
101
+ - `train_linear_regression` - Linear regression
102
+ - `train_logistic_regression` - Logistic regression
103
+ - `train_random_forest_classifier` - Random forest classification
104
+ - `train_random_forest_regressor` - Random forest regression
105
+ - `evaluate_model` - Model evaluation metrics
106
+
107
+ ### Time Series (ARIMA)
108
+ - `check_stationarity` - ADF/KPSS tests
109
+ - `fit_arima` - Fit ARIMA models
110
+ - `forecast_arima` - Generate forecasts
111
+ - `find_optimal_arima` - Auto parameter search
112
+
113
+ ## How It Works
114
+
115
+ ```
116
+ ┌─────────────────────────────────────────────────────────────┐
117
+ │ MCP Client │
118
+ │ (ChatGPT, Claude, Cursor, VS Code) │
119
+ └─────────────────────────┬───────────────────────────────────┘
120
+ │ MCP Protocol
121
+
122
+ ┌─────────────────────────────────────────────────────────────┐
123
+ │ stats-compass-mcp │
124
+ │ ┌─────────────────────────────────────────────────────┐ │
125
+ │ │ MCP Server (this package) │ │
126
+ │ │ • Registers tools from stats-compass-core │ │
127
+ │ │ • Manages DataFrameState per session │ │
128
+ │ │ • Converts tool results to MCP responses │ │
129
+ │ └─────────────────────────────────────────────────────┘ │
130
+ │ │ │
131
+ │ ▼ │
132
+ │ ┌─────────────────────────────────────────────────────┐ │
133
+ │ │ stats-compass-core (PyPI) │ │
134
+ │ │ • DataFrameState (server-side state) │ │
135
+ │ │ • 40+ deterministic tools │ │
136
+ │ │ • Pydantic schemas for all inputs/outputs │ │
137
+ │ └─────────────────────────────────────────────────────┘ │
138
+ └─────────────────────────────────────────────────────────────┘
139
+ ```
140
+
141
+ ## Development
142
+
143
+ ```bash
144
+ # Clone and install
145
+ git clone https://github.com/oogunbiyi21/stats-compass-mcp.git
146
+ cd stats-compass-mcp
147
+ poetry install
148
+
149
+ # Run tests
150
+ poetry run pytest
151
+
152
+ # Run the server locally
153
+ poetry run stats-compass-mcp serve
154
+ ```
155
+
156
+ ## Related Projects
157
+
158
+ - [stats-compass-core](https://github.com/oogunbiyi21/stats-compass-core) - The underlying toolkit
159
+ - [stats-compass](https://github.com/oogunbiyi21/stats-compass) - Streamlit chat UI for data analysis
160
+
161
+ ## License
162
+
163
+ MIT
@@ -0,0 +1,53 @@
1
+ [tool.poetry]
2
+ name = "stats-compass-mcp"
3
+ version = "0.1.0"
4
+ description = "MCP server exposing stats-compass-core tools to LLMs like ChatGPT, Claude, and Gemini"
5
+ authors = ["Olatunji Ogunbiyi <oogunbiyi21@users.noreply.github.com>"]
6
+ license = "MIT"
7
+ readme = "README.md"
8
+ packages = [{include = "stats_compass_mcp"}]
9
+ keywords = ["mcp", "llm", "data-science", "pandas", "ai-agents", "chatgpt", "claude"]
10
+ classifiers = [
11
+ "Development Status :: 3 - Alpha",
12
+ "Intended Audience :: Developers",
13
+ "Intended Audience :: Science/Research",
14
+ "License :: OSI Approved :: MIT License",
15
+ "Programming Language :: Python :: 3",
16
+ "Programming Language :: Python :: 3.11",
17
+ "Programming Language :: Python :: 3.12",
18
+ "Topic :: Scientific/Engineering",
19
+ "Topic :: Software Development :: Libraries :: Python Modules",
20
+ ]
21
+
22
+ [tool.poetry.dependencies]
23
+ python = "^3.11"
24
+ stats-compass-core = {extras = ["all"], version = "^0.1.3"}
25
+ mcp = "^1.0.0"
26
+
27
+ [tool.poetry.group.dev.dependencies]
28
+ pytest = "^8.2.0"
29
+ pytest-asyncio = "^0.24.0"
30
+ ruff = "^0.8.0"
31
+ mypy = "^1.0.0"
32
+
33
+ [tool.poetry.scripts]
34
+ stats-compass-mcp = "stats_compass_mcp.cli:main"
35
+
36
+ [build-system]
37
+ requires = ["poetry-core>=2.0.0,<3.0.0"]
38
+ build-backend = "poetry.core.masonry.api"
39
+
40
+ [tool.pytest.ini_options]
41
+ testpaths = ["tests"]
42
+ asyncio_mode = "auto"
43
+
44
+ [tool.ruff]
45
+ line-length = 88
46
+ target-version = "py311"
47
+
48
+ [tool.ruff.lint]
49
+ select = ["E", "F", "I", "W"]
50
+
51
+ [tool.mypy]
52
+ python_version = "3.11"
53
+ strict = true
@@ -0,0 +1,7 @@
1
+ """
2
+ stats-compass-mcp: MCP server for stats-compass-core tools.
3
+
4
+ Exposes data analysis tools to LLMs via the Model Context Protocol.
5
+ """
6
+
7
+ __version__ = "0.1.0"
@@ -0,0 +1,57 @@
1
+ """
2
+ CLI entrypoint for stats-compass-mcp.
3
+ """
4
+
5
+ import argparse
6
+ import sys
7
+ import logging
8
+
9
+ # Setup debug logging to file
10
+ logging.basicConfig(
11
+ filename='/tmp/stats_compass_mcp_debug.log',
12
+ level=logging.DEBUG,
13
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
14
+ )
15
+
16
+ def main() -> None:
17
+ """Main CLI entrypoint."""
18
+ parser = argparse.ArgumentParser(
19
+ prog="stats-compass-mcp",
20
+ description="MCP server for stats-compass-core data analysis tools",
21
+ )
22
+
23
+ subparsers = parser.add_subparsers(dest="command", help="Available commands")
24
+
25
+ # serve command
26
+ serve_parser = subparsers.add_parser("serve", help="Start the MCP server")
27
+ serve_parser.add_argument(
28
+ "--transport",
29
+ choices=["stdio", "sse"],
30
+ default="stdio",
31
+ help="Transport protocol (default: stdio)",
32
+ )
33
+ serve_parser.add_argument(
34
+ "--port",
35
+ type=int,
36
+ default=8000,
37
+ help="Port for SSE transport (default: 8000)",
38
+ )
39
+
40
+ # list-tools command
41
+ subparsers.add_parser("list-tools", help="List all available tools")
42
+
43
+ args = parser.parse_args()
44
+
45
+ if args.command == "serve":
46
+ from .server import run_server
47
+ run_server(transport=args.transport, port=args.port)
48
+ elif args.command == "list-tools":
49
+ from .tools import list_tools
50
+ list_tools()
51
+ else:
52
+ parser.print_help()
53
+ sys.exit(1)
54
+
55
+
56
+ if __name__ == "__main__":
57
+ main()
@@ -0,0 +1,129 @@
1
+ """
2
+ MCP Server for stats-compass-core.
3
+
4
+ Exposes all tools via the Model Context Protocol.
5
+ """
6
+
7
+ import json
8
+ import logging
9
+ from typing import Any
10
+
11
+ from mcp.server import Server
12
+ from mcp.server.stdio import stdio_server
13
+ from mcp.types import (
14
+ Tool,
15
+ TextContent,
16
+ )
17
+ from pydantic import BaseModel
18
+
19
+ from stats_compass_core.state import DataFrameState
20
+ from stats_compass_core.registry import registry
21
+
22
+ from .tools import get_all_tools
23
+
24
+ # Configure logging
25
+ logging.basicConfig(level=logging.INFO)
26
+ logger = logging.getLogger(__name__)
27
+
28
+
29
+ def create_server() -> Server:
30
+ """Create and configure the MCP server."""
31
+ server = Server("stats-compass")
32
+
33
+ # Server-side state - one DataFrameState per session
34
+ state = DataFrameState()
35
+
36
+ # Load all tools from stats-compass-core
37
+ registry.auto_discover()
38
+ tools = get_all_tools()
39
+
40
+ @server.list_tools()
41
+ async def list_tools() -> list[Tool]:
42
+ """List all available tools."""
43
+ mcp_tools = []
44
+ for tool in tools:
45
+ mcp_tool = Tool(
46
+ name=tool["name"],
47
+ description=tool["description"] or f"{tool['category']} tool: {tool['original_name']}",
48
+ inputSchema=tool.get("input_schema", {"type": "object", "properties": {}}),
49
+ )
50
+ mcp_tools.append(mcp_tool)
51
+ return mcp_tools
52
+
53
+ @server.call_tool()
54
+ async def call_tool(name: str, arguments: dict[str, Any]) -> list[TextContent]:
55
+ """Execute a tool and return results."""
56
+ logger.info(f"Tool called: {name} with args: {arguments}")
57
+
58
+ # Find the tool
59
+ tool_info = None
60
+ for t in tools:
61
+ if t["name"] == name:
62
+ tool_info = t
63
+ break
64
+
65
+ if not tool_info:
66
+ return [TextContent(
67
+ type="text",
68
+ text=json.dumps({"error": f"Tool '{name}' not found"}),
69
+ )]
70
+
71
+ try:
72
+ # Validate and parse input if schema exists
73
+ if "input_model" in tool_info:
74
+ params = tool_info["input_model"](**arguments)
75
+ else:
76
+ params = arguments
77
+
78
+ # Call the tool with state injected
79
+ result = tool_info["function"](state, params)
80
+
81
+ # Convert result to JSON-serializable format
82
+ if isinstance(result, BaseModel):
83
+ result_data = result.model_dump()
84
+ elif hasattr(result, "to_dict"):
85
+ result_data = result.to_dict()
86
+ else:
87
+ result_data = result
88
+
89
+ return [TextContent(
90
+ type="text",
91
+ text=json.dumps(result_data, default=str, indent=2),
92
+ )]
93
+
94
+ except Exception as e:
95
+ logger.error(f"Tool error: {e}")
96
+ return [TextContent(
97
+ type="text",
98
+ text=json.dumps({
99
+ "error": str(e),
100
+ "error_type": type(e).__name__,
101
+ }),
102
+ )]
103
+
104
+ return server
105
+
106
+
107
+ def run_server(transport: str = "stdio", port: int = 8000) -> None:
108
+ """Run the MCP server."""
109
+ import asyncio
110
+
111
+ server = create_server()
112
+
113
+ if transport == "stdio":
114
+ logger.info("Starting Stats Compass MCP server (stdio transport)...")
115
+ asyncio.run(run_stdio(server))
116
+ elif transport == "sse":
117
+ logger.info(f"Starting Stats Compass MCP server (SSE on port {port})...")
118
+ # SSE transport would go here - for now just stdio
119
+ raise NotImplementedError("SSE transport not yet implemented")
120
+
121
+
122
+ async def run_stdio(server: Server) -> None:
123
+ """Run the server with stdio transport."""
124
+ async with stdio_server() as (read_stream, write_stream):
125
+ await server.run(
126
+ read_stream,
127
+ write_stream,
128
+ server.create_initialization_options(),
129
+ )
@@ -0,0 +1,65 @@
1
+ """
2
+ Tool loader and registry bridge for MCP.
3
+
4
+ Loads all tools from stats-compass-core and prepares them for MCP registration.
5
+ """
6
+
7
+ from typing import Any
8
+
9
+ from stats_compass_core.registry import registry
10
+
11
+
12
+ def get_all_tools() -> list[dict[str, Any]]:
13
+ """
14
+ Get all registered tools from stats-compass-core.
15
+
16
+ Returns:
17
+ List of tool metadata dicts with name, category, description, and schema.
18
+ """
19
+ # Ensure tools are discovered
20
+ registry.auto_discover()
21
+
22
+ tools = []
23
+ for metadata in registry.list_tools():
24
+ tool_info: dict[str, Any] = {
25
+ "name": f"{metadata.category}_{metadata.name}",
26
+ "category": metadata.category,
27
+ "original_name": metadata.name,
28
+ "description": metadata.description,
29
+ "function": metadata.function,
30
+ }
31
+
32
+ # Add JSON schema if available
33
+ if metadata.input_schema:
34
+ tool_info["input_schema"] = metadata.input_schema.model_json_schema()
35
+ tool_info["input_model"] = metadata.input_schema
36
+
37
+ tools.append(tool_info)
38
+
39
+ return tools
40
+
41
+
42
+ def list_tools() -> None:
43
+ """Print all available tools to stdout."""
44
+ tools = get_all_tools()
45
+
46
+ print(f"\n📊 Stats Compass MCP Tools ({len(tools)} available)\n")
47
+ print("=" * 60)
48
+
49
+ # Group by category
50
+ by_category: dict[str, list[dict[str, Any]]] = {}
51
+ for tool in tools:
52
+ cat = tool["category"]
53
+ if cat not in by_category:
54
+ by_category[cat] = []
55
+ by_category[cat].append(tool)
56
+
57
+ for category, cat_tools in sorted(by_category.items()):
58
+ print(f"\n🔧 {category.upper()} ({len(cat_tools)} tools)")
59
+ print("-" * 40)
60
+ for tool in cat_tools:
61
+ desc = tool["description"][:50] + "..." if len(tool["description"]) > 50 else tool["description"]
62
+ print(f" • {tool['original_name']}: {desc}")
63
+
64
+ print("\n" + "=" * 60)
65
+ print("Run 'stats-compass-mcp serve' to start the MCP server.\n")