Metadata-Version: 2.4
Name: sktime-mcp
Version: 0.1.0
Summary: MCP (Model Context Protocol) layer for sktime - Registry-Driven for LLMs
Author: sktime-mcp contributors
License: BSD 3-Clause License
        
        Copyright (c) 2026 - present, The sktime developers.
        
        All rights reserved.
        
        Redistribution and use in source and binary forms, with or without
        modification, are permitted provided that the following conditions are met:
        
        * Redistributions of source code must retain the above copyright notice, this
          list of conditions and the following disclaimer.
        
        * Redistributions in binary form must reproduce the above copyright notice,
          this list of conditions and the following disclaimer in the documentation
          and/or other materials provided with the distribution.
        
        * Neither the name of the copyright holder nor the names of its
          contributors may be used to endorse or promote products derived from
          this software without specific prior written permission.
        
        THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
        AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
        FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
        CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
        OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
License-File: LICENSE
Keywords: forecasting,llm,machine-learning,mcp,sktime,time-series
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: BSD License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Requires-Dist: mcp>=1.0.0
Requires-Dist: numpy>=1.21.0
Requires-Dist: pandas>=1.5.0
Requires-Dist: pmdarima>=2.0.0
Requires-Dist: scikit-learn>=1.0.0
Requires-Dist: sktime>=0.24.0
Requires-Dist: statsmodels>=0.13.0
Provides-Extra: all
Requires-Dist: openpyxl>=3.0.0; extra == 'all'
Requires-Dist: pmdarima>=2.0.0; extra == 'all'
Requires-Dist: prophet>=1.1.0; extra == 'all'
Requires-Dist: psycopg2-binary>=2.9.0; extra == 'all'
Requires-Dist: pyarrow>=10.0.0; extra == 'all'
Requires-Dist: pymysql>=1.0.0; extra == 'all'
Requires-Dist: sqlalchemy>=2.0.0; extra == 'all'
Requires-Dist: statsforecast>=1.4.0; extra == 'all'
Requires-Dist: statsmodels>=0.13.0; extra == 'all'
Requires-Dist: tbats>=1.1.0; extra == 'all'
Provides-Extra: dev
Requires-Dist: black>=23.0.0; extra == 'dev'
Requires-Dist: mkdocs>=1.5.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Provides-Extra: dl
Requires-Dist: tensorflow>=2.9.0; extra == 'dl'
Requires-Dist: torch>=1.9.0; extra == 'dl'
Provides-Extra: files
Requires-Dist: openpyxl>=3.0.0; extra == 'files'
Requires-Dist: pyarrow>=10.0.0; extra == 'files'
Provides-Extra: forecasting
Requires-Dist: prophet>=1.1.0; extra == 'forecasting'
Requires-Dist: statsforecast>=1.4.0; extra == 'forecasting'
Requires-Dist: tbats>=1.1.0; extra == 'forecasting'
Provides-Extra: sql
Requires-Dist: psycopg2-binary>=2.9.0; extra == 'sql'
Requires-Dist: pymysql>=1.0.0; extra == 'sql'
Requires-Dist: sqlalchemy>=2.0.0; extra == 'sql'
Description-Content-Type: text/markdown

# sktime-mcp

**MCP (Model Context Protocol) layer for sktime - Registry-Driven for LLMs**

A semantic engine that exposes sktime's native registry and semantics to Large Language Models, enabling them to:

- 🔍 **Discover** valid estimators
- 🧠 **Reason** about estimator capabilities  
- 🔗 **Compose** compatible estimators
- ⚡ **Execute** real sktime workflows on real data

## 🎯 Design Philosophy

This MCP is **not** just documentation or static code analysis. It is a **semantic engine** for programmatic model usage.

### Key Principles

1. **sktime as Source of Truth** - No AST parsing, no repo indexing, no heuristics. All structure comes from `all_estimators`, estimator tags, and sktime's API contracts.

2. **Registry-First** - Instead of `File → Class → Infer Relationships`, we do `Registry → Semantics → Safe Execution`.

3. **Minimal MCP Surface** - Exposes only what an LLM needs: Discovery, Description, Instantiation, Execution.

## 🛠️ Installation

```bash
# Install from source
pip install -e .

# With all optional dependencies
pip install -e ".[all]"

# Development installation
pip install -e ".[dev]"
```

## 🚀 Quick Start

### Running the MCP Server

```bash
# Start the MCP server
sktime-mcp

# Or run directly
python -m sktime_mcp.server
```

### Connecting from an LLM Client

The server uses stdio transport by default, compatible with Claude Desktop and other MCP clients.

Add to your Claude Desktop config (`~/.config/claude/claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "sktime": {
      "command": "sktime-mcp"
    }
  }
}
```

## 📚 Available Tools

### Discovery & Search

#### 1. `list_estimators`
Discover estimators by task type and capability tags.

**Arguments:**
- `task` (optional): Task type filter (`"forecasting"`, `"classification"`, `"regression"`, `"transformation"`, `"clustering"`)
- `tags` (optional): Filter by capability tags (e.g., `{"capability:pred_int": true}`)
- `limit` (optional): Maximum results (default: 50)

**Example:**
```json
{
  "task": "forecasting",
  "tags": {
    "capability:pred_int": true
  },
  "limit": 10
}
```

**Returns:** List of matching estimators with name, task, and summary info.

---

#### 2. `search_estimators`
Search estimators by name or description using text query.

**Arguments:**
- `query` (required): Search string (case-insensitive)
- `limit` (optional): Maximum results (default: 20)

**Example:**
```json
{
  "query": "ARIMA",
  "limit": 5
}
```

**Returns:** List of estimators matching the search query.

---

#### 3. `describe_estimator`
Get detailed information about a specific estimator's capabilities.

**Arguments:**
- `estimator` (required): Name of the estimator (e.g., `"ARIMA"`, `"NaiveForecaster"`)

**Example:**
```json
{
  "estimator": "ARIMA"
}
```

**Returns:** Full estimator details including tags, hyperparameters, docstring, and module path.

---

#### 4. `get_available_tags`
List all queryable capability tags across all estimators.

**Arguments:** None

**Returns:** List of all available tags (e.g., `["capability:pred_int", "handles-missing-data", ...]`)

---

### Instantiation

#### 5. `instantiate_estimator`
Create a single estimator instance and return a handle.

**Arguments:**
- `estimator` (required): Name of the estimator to instantiate
- `params` (optional): Hyperparameters for the estimator

**Example:**
```json
{
  "estimator": "ARIMA",
  "params": {
    "order": [1, 1, 1],
    "suppress_warnings": true
  }
}
```

**Returns:** `{"success": true, "handle": "est_abc123", "estimator": "ARIMA", "params": {...}}`

---

#### 6. `instantiate_pipeline` 
Create a complete pipeline from a list of components (transformers → forecaster).

**Arguments:**
- `components` (required): List of estimator names in pipeline order
- `params_list` (optional): List of parameter dicts for each component

**Example:**
```json
{
  "components": ["ConditionalDeseasonalizer", "Detrender", "ARIMA"],
  "params_list": [{}, {}, {"order": [1, 1, 1]}]
}
```

**Returns:** `{"success": true, "handle": "est_xyz789", "pipeline": "ConditionalDeseasonalizer → Detrender → ARIMA", ...}`

**Note:** This solves the "steps problem" - you don't need to instantiate components separately!

---

## 📖 Documentation

Project documentation lives in `docs/` and can be served locally with MkDocs:

```bash
pip install -e ".[dev]"
mkdocs serve
```

The MkDocs config is in `mkdocs.yml`.

### Validation

#### 7. `validate_pipeline`
Check if a proposed pipeline composition is valid before instantiation.

**Arguments:**
- `components` (required): List of estimator names in pipeline order

**Example:**
```json
{
  "components": ["Detrender", "ARIMA"]
}
```

**Returns:** `{"valid": true/false, "errors": [...], "warnings": [...], "suggestions": [...]}`

---

### Execution

#### 8. `fit_predict`
Execute a complete workflow: load dataset, fit estimator, and generate predictions.

**Arguments:**
- `estimator_handle` (required): Handle from `instantiate_estimator` or `instantiate_pipeline`
- `dataset` (required): Dataset name (e.g., `"airline"`, `"sunspots"`, `"lynx"`)
- `horizon` (optional): Forecast horizon (default: 12)

**Example:**
```json
{
  "estimator_handle": "est_abc123",
  "dataset": "airline",
  "horizon": 12
}
```

**Returns:** `{"success": true, "predictions": {1: 450.2, 2: 455.1, ...}, "horizon": 12}`

---

### Datasets

#### 9. `list_datasets`
List all available demo datasets for testing and experimentation.

**Arguments:** None

**Returns:** `{"success": true, "datasets": ["airline", "sunspots", "lynx", "shampoo", ...]}`

---

### Handle Management

#### 10. `list_handles`
List all active estimator handles and their status.

**Arguments:** None

**Returns:** List of active handles with metadata (estimator name, fitted status, creation time)

---

#### 11. `release_handle`
Release an estimator handle and free memory.

**Arguments:**
- `handle` (required): Handle ID to release

**Example:**
```json
{
  "handle": "est_abc123"
}
```

**Returns:** `{"success": true, "message": "Handle released"}`

## 🔄 Example LLM Flows

### Flow 1: Simple Forecasting

**User Prompt:** "Forecast monthly airline passengers using a probabilistic model."

**LLM Steps:**

1. **Discover Models**
   ```
   list_estimators(task="forecasting", tags={"capability:pred_int": true})
   ```

2. **Inspect Choice**
   ```
   describe_estimator(estimator="ARIMA")
   ```

3. **Instantiate**
   ```
   instantiate_estimator(estimator="ARIMA", params={"order": [1,1,1]})
   → Returns: {"handle": "est_abc123"}
   ```

4. **Execute**
   ```
   fit_predict(estimator_handle="est_abc123", dataset="airline", horizon=12)
   → Returns: {"predictions": {1: 450.2, 2: 455.1, ...}}
   ```

### Flow 2: Pipeline Forecasting ⭐

**User Prompt:** "Forecast with deseasonalization and detrending preprocessing."

**LLM Steps:**

1. **Validate Composition**
   ```
   validate_pipeline(components=["ConditionalDeseasonalizer", "Detrender", "ARIMA"])
   → Returns: {"valid": true}
   ```

2. **Instantiate Pipeline** (single call!)
   ```
   instantiate_pipeline(
     components=["ConditionalDeseasonalizer", "Detrender", "ARIMA"],
     params_list=[{}, {}, {"order": [1,1,1]}]
   )
   → Returns: {"handle": "est_xyz789", "pipeline": "ConditionalDeseasonalizer → Detrender → ARIMA"}
   ```

3. **Execute**
   ```
   fit_predict(estimator_handle="est_xyz789", dataset="airline", horizon=12)
   → Returns: {"predictions": {...}}
   ```

## 📁 Project Structure

```
sktime_mcp/
├── src/sktime_mcp/
│   ├── server.py           # MCP server entry point
│   ├── registry/           # Registry interface & tag resolver
│   ├── composition/        # Pipeline composition validator
│   ├── runtime/            # Execution engine & handle management
│   └── tools/              # MCP tool implementations
├── examples/               # Usage examples
└── tests/                  # Test suite
```

## 🧪 Running Tests

```bash
pytest tests/
```
