Skip to content

Commit c75c493

Browse files
authored
[ENH] Enrich get_available_tags with rich metadata (description, value_type, applies_to) (#37)
#### Reference Issues/PRs Fixes #30. #### What does this implement/fix? Explain your changes. Currently, `get_available_tags()` returns only a flat list of tag name strings with no additional context. This causes LLMs to frequently select the wrong tag or wrong value when filtering estimators (e.g., using `"capability:multivariate": true` instead of the correct `"scitype:y": "multivariate"`). This PR enhances `get_available_tags()` to return rich metadata for each tag by leveraging `sktime.registry.all_tags()`. Each tag entry now includes: - **`tag`**: the tag name (e.g., `"scitype:y"`) - **`description`**: human-readable explanation (e.g., `"The scitype of the target variable y"`) - **`value_type`**: expected value type (e.g., `"str"`, `"bool"`) - **`applies_to`**: list of estimator types the tag applies to (e.g., `["forecaster", "classifier"]`) **Files changed:** - `src/sktime_mcp/registry/interface.py` — Updated `get_available_tags()` to return rich metadata from `sktime.registry.all_tags()` - `src/sktime_mcp/server.py` — Updated tool description to reflect new output format Output now after changes (trucated) : ```log { "success": true, "tags": [ { "tag": "capability:multivariate", "description": "does the object natively support time series with 2 or more variables?", "value_type": "bool", "applies_to": ["classifier", "clusterer", "early_classifier", "metric", "param_est", "regressor", "transformer"] }, { "tag": "capability:pred_int", "description": "does the forecaster implement predict_interval or predict_quantiles?", "value_type": "bool", "applies_to": ["forecaster"] }, { "tag": "scitype:y", "description": "The scitype of the target variable y", "value_type": "str", "applies_to": ["forecaster", "classifier", "regressor"] } ] } ``` #### Does your contribution introduce a new dependency? If yes, which one? No. This uses `sktime.registry.all_tags()` which is already part of the existing `sktime` dependency. #### What should a reviewer concentrate their feedback on? - Whether the updated tool description in `server.py` is clear enough for LLM consumption #### Any other comments? This change is fully backward-compatible at the tool level — the response key is still `"tags"`, but each entry is now a dict instead of a string. No new dependencies are introduced. #### PR checklist ##### For all contributions - [ ] I've added myself to the [list of contributors](https://github.com/alan-turing-institute/sktime/blob/main/.all-contributorsrc). - [ ] Optionally, I've updated sktime's [CODEOWNERS](https://github.com/alan-turing-institute/sktime/blob/main/CODEOWNERS) to receive notifications about future changes to these files. - [ ] I've added unit tests and made sure they pass locally. ##### For new estimators - N/A
1 parent 5aae774 commit c75c493

2 files changed

Lines changed: 46 additions & 4 deletions

File tree

src/sktime_mcp/registry/interface.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -256,10 +256,47 @@ def get_available_tasks(self) -> List[str]:
256256
"""Get list of available task types."""
257257
return list(self.TASK_MAP.values())
258258

259-
def get_available_tags(self) -> List[str]:
260-
"""Get list of all available tags across all estimators."""
259+
def get_available_tags(self) -> List[Dict[str, Any]]:
260+
"""Get rich metadata for all available tags using sktime's registry.
261+
262+
Returns a list of dicts, each containing:
263+
- tag: the tag name (e.g., "scitype:y")
264+
- description: human-readable explanation of what the tag means
265+
- value_type: the expected value type (e.g., "bool", "str")
266+
- applies_to: list of estimator types this tag applies to
267+
"""
261268
self._ensure_loaded()
262-
return sorted(list(self._all_tags))
269+
270+
try:
271+
from sktime.registry import all_tags
272+
tags_df = all_tags(as_dataframe=True)
273+
except ImportError:
274+
# Fallback to old behaviour if all_tags is not available
275+
return [{"tag": t} for t in sorted(self._all_tags)]
276+
277+
result = []
278+
for _, row in tags_df.iterrows():
279+
# Normalize scitype to a list for consistency
280+
scitype = row.get("scitype", [])
281+
if isinstance(scitype, str):
282+
scitype = [scitype]
283+
elif not isinstance(scitype, list):
284+
scitype = list(scitype) if hasattr(scitype, '__iter__') else [str(scitype)]
285+
286+
# Convert value_type to a JSON-safe string representation
287+
value_type = row.get("type", "")
288+
if not isinstance(value_type, str):
289+
value_type = str(value_type)
290+
291+
result.append({
292+
"tag": row["name"],
293+
"description": row.get("description", ""),
294+
"value_type": value_type,
295+
"applies_to": scitype,
296+
})
297+
298+
result.sort(key=lambda x: x["tag"])
299+
return result
263300

264301
def search_estimators(self, query: str) -> List[EstimatorNode]:
265302
"""

src/sktime_mcp/server.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,12 @@ async def list_tools() -> List[Tool]:
248248
),
249249
Tool(
250250
name="get_available_tags",
251-
description="List all queryable capability tags",
251+
description=(
252+
"List all queryable capability tags with rich metadata. "
253+
"Returns tag name, description, expected value type, and which "
254+
"estimator types the tag applies to. ALWAYS call this before "
255+
"using tags in list_estimators to ensure correct tag names and values."
256+
),
252257
inputSchema={"type": "object", "properties": {}},
253258
),
254259
Tool(

0 commit comments

Comments
 (0)