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
-
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. -
Registry-First - Instead of
File → Class → Infer Relationships, we doRegistry → Semantics → Safe Execution. -
Minimal MCP Surface - Exposes only what an LLM needs: Discovery, Description, Instantiation, Execution.
🛠️ Installation
# 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
# 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):
{
"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:
{
"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:
{
"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:
{
"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 instantiateparams(optional): Hyperparameters for the estimator
Example:
{
"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 orderparams_list(optional): List of parameter dicts for each component
Example:
{
"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:
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:
{
"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 frominstantiate_estimatororinstantiate_pipelinedataset(required): Dataset name (e.g.,"airline","sunspots","lynx")horizon(optional): Forecast horizon (default: 12)
Example:
{
"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:
{
"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:
-
Discover Models
list_estimators(task="forecasting", tags={"capability:pred_int": true}) -
Inspect Choice
describe_estimator(estimator="ARIMA") -
Instantiate
instantiate_estimator(estimator="ARIMA", params={"order": [1,1,1]}) → Returns: {"handle": "est_abc123"} -
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:
-
Validate Composition
validate_pipeline(components=["ConditionalDeseasonalizer", "Detrender", "ARIMA"]) → Returns: {"valid": true} -
Instantiate Pipeline (single call!)
instantiate_pipeline( components=["ConditionalDeseasonalizer", "Detrender", "ARIMA"], params_list=[{}, {}, {"order": [1,1,1]}] ) → Returns: {"handle": "est_xyz789", "pipeline": "ConditionalDeseasonalizer → Detrender → ARIMA"} -
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
pytest tests/
Metadata
Release files for sktimecopilot 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| sktimecopilot-0.1.0.tar.gz | 42.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| sktimecopilot-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 97.0 kB
Release files / sktimecopilot-0.1.0.tar.gz
| Download URL | sktimecopilot-0.1.0.tar.gz |
|---|---|
| Size | 42.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
91378da2cc59ff51e90256b55b386313a4d424af4386d7ba2c6f337a5bfa02ff
|
|
BLAKE2b-256 checksum How to use checksums |
26b8cfa6db4bc93f227c9c04ae0690919d9d19597f1a7fcffeb9f2c7cb58b720
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / sktimecopilot-0.1.0-py3-none-any.whl
| Download URL | sktimecopilot-0.1.0-py3-none-any.whl |
|---|---|
| Size | 54.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
987d13d0dcb0644a2e4b03d6f6555ae37bb2afc706df56df304b3564c908ef01
|
|
BLAKE2b-256 checksum How to use checksums |
3b69d470487af610ccc0274bb41c8afe3e9e6c05966e0da615264a05e7a5163e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|