|
""" |
|
Simple HuggingFace MCP Spaces Finder Module - Corrected Version |
|
A minimal module to discover MCP servers on HuggingFace Spaces. |
|
Fixed to fetch ALL available MCP servers using proper pagination. |
|
Usage: |
|
from mcp_spaces_finder import create_simple_mcp_selector |
|
|
|
# One-liner in your Gradio app |
|
dropdown, textbox = create_simple_mcp_selector() |
|
""" |
|
import gradio as gr |
|
from huggingface_hub import list_spaces |
|
import time |
|
from typing import List, Tuple |
|
|
|
class SimpleMCPFinder: |
|
"""Simple MCP spaces finder with caching and proper pagination.""" |
|
|
|
def __init__(self, cache_duration: int = 300): |
|
self.cache = None |
|
self.cache_time = None |
|
self.cache_duration = cache_duration |
|
|
|
def get_mcp_spaces(self) -> List[str]: |
|
"""Get list of ALL running MCP space IDs using proper pagination.""" |
|
|
|
|
|
if (self.cache is not None and |
|
self.cache_time is not None and |
|
time.time() - self.cache_time < self.cache_duration): |
|
return self.cache |
|
|
|
print("Fetching ALL MCP spaces...") |
|
|
|
|
|
|
|
spaces = list(list_spaces( |
|
filter="mcp-server", |
|
sort="likes", |
|
direction=-1, |
|
limit=5000, |
|
full=True |
|
)) |
|
|
|
|
|
space_ids = [space.id for space in spaces] |
|
|
|
|
|
self.cache = space_ids |
|
self.cache_time = time.time() |
|
|
|
print(f"Found {len(space_ids)} MCP spaces") |
|
return space_ids |
|
|
|
def get_mcp_spaces_paginated(self) -> List[str]: |
|
"""Alternative method: Get ALL MCP spaces using explicit pagination if needed.""" |
|
|
|
|
|
if (self.cache is not None and |
|
self.cache_time is not None and |
|
time.time() - self.cache_time < self.cache_duration): |
|
return self.cache |
|
|
|
print("Fetching ALL MCP spaces with pagination...") |
|
|
|
all_space_ids = [] |
|
limit_per_page = 1000 |
|
|
|
|
|
|
|
try: |
|
spaces = list(list_spaces( |
|
filter="mcp-server", |
|
sort="likes", |
|
direction=-1, |
|
limit=None, |
|
full=True |
|
)) |
|
all_space_ids = [space.id for space in spaces] |
|
|
|
except Exception as e: |
|
print(f"Error with unlimited fetch, trying with high limit: {e}") |
|
|
|
spaces = list(list_spaces( |
|
filter="mcp-server", |
|
sort="likes", |
|
direction=-1, |
|
limit=5000, |
|
full=True |
|
)) |
|
all_space_ids = [space.id for space in spaces] |
|
|
|
|
|
self.cache = all_space_ids |
|
self.cache_time = time.time() |
|
|
|
print(f"Found {len(all_space_ids)} MCP spaces total") |
|
return all_space_ids |
|
|
|
|
|
_finder = SimpleMCPFinder() |
|
|
|
def create_simple_mcp_selector( |
|
dropdown_label: str = "π€ Select MCP Server", |
|
textbox_label: str = "Selected MCP Server", |
|
placeholder: str = "No server selected" |
|
) -> Tuple[gr.Dropdown, gr.Textbox]: |
|
""" |
|
Create a simple MCP selector with dropdown and textbox. |
|
|
|
Args: |
|
dropdown_label (str): Label for the dropdown |
|
textbox_label (str): Label for the textbox |
|
placeholder (str): Placeholder text when nothing selected |
|
|
|
Returns: |
|
Tuple[gr.Dropdown, gr.Textbox]: The dropdown and textbox components |
|
""" |
|
|
|
|
|
spaces = _finder.get_mcp_spaces() |
|
|
|
|
|
dropdown = gr.Dropdown( |
|
choices=spaces, |
|
label=f"{dropdown_label} ({len(spaces)} available)", |
|
value=None, |
|
allow_custom_value=True, |
|
info="Choose from discovered MCP spaces or type a custom space ID" |
|
) |
|
|
|
|
|
textbox = gr.Textbox( |
|
label=textbox_label, |
|
value=placeholder, |
|
interactive=False |
|
) |
|
|
|
|
|
def update_textbox(selected_value): |
|
return selected_value if selected_value else placeholder |
|
|
|
dropdown.change( |
|
fn=update_textbox, |
|
inputs=[dropdown], |
|
outputs=[textbox] |
|
) |
|
|
|
return dropdown, textbox |
|
|
|
def refresh_mcp_spaces(): |
|
"""Clear cache to force refresh.""" |
|
_finder.cache = None |
|
_finder.cache_time = None |
|
|
|
def test_space_exists(space_id: str) -> bool: |
|
"""Test if a specific space exists in our discovered list.""" |
|
spaces = _finder.get_mcp_spaces() |
|
return space_id in spaces |
|
|
|
def debug_search_for_spaces(space_ids: List[str]): |
|
"""Debug function to check if specific spaces are found.""" |
|
spaces = _finder.get_mcp_spaces() |
|
print(f"Total MCP spaces found: {len(spaces)}") |
|
|
|
for space_id in space_ids: |
|
if space_id in spaces: |
|
print(f"β
Found: {space_id}") |
|
else: |
|
print(f"β Missing: {space_id}") |
|
|
|
|
|
print(f"\nFirst 10 spaces found:") |
|
for i, space in enumerate(spaces[:10]): |
|
print(f" {i+1}. {space}") |
|
|
|
if __name__ == "__main__": |
|
|
|
test_spaces = [ |
|
"ysharma/Kokoro-TTS-mcp-test", |
|
"ysharma/ltx-video-distilled", |
|
"ysharma/dalle-3-xl-lora-v2" |
|
] |
|
|
|
print("Testing MCP space discovery...") |
|
debug_search_for_spaces(test_spaces) |
|
|
|
|