File size: 3,053 Bytes
04ca5c4
230e011
 
 
04ca5c4
230e011
04ca5c4
230e011
 
04ca5c4
 
 
230e011
04ca5c4
230e011
04ca5c4
 
230e011
 
04ca5c4
 
230e011
 
04ca5c4
 
230e011
 
04ca5c4
230e011
 
 
 
 
04ca5c4
230e011
04ca5c4
230e011
04ca5c4
 
230e011
04ca5c4
230e011
04ca5c4
 
 
230e011
 
04ca5c4
230e011
 
 
04ca5c4
230e011
 
04ca5c4
230e011
 
04ca5c4
230e011
 
 
 
 
04ca5c4
230e011
04ca5c4
 
230e011
 
 
04ca5c4
 
230e011
04ca5c4
 
230e011
 
04ca5c4
230e011
 
 
 
 
04ca5c4
 
230e011
 
 
 
 
 
04ca5c4
230e011
 
 
04ca5c4
230e011
 
 
 
 
04ca5c4
230e011
04ca5c4
230e011
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
"""
Simple HuggingFace MCP Spaces Finder Module
A minimal module to discover MCP servers on HuggingFace Spaces.
Just a dropdown that displays the selected value in a textbox.
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
from concurrent.futures import ThreadPoolExecutor, as_completed

class SimpleMCPFinder:
    """Simple MCP spaces finder with caching."""
    
    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 running MCP space IDs."""
        
        # Check cache
        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 MCP spaces...")
        
        # Get MCP spaces sorted by likes
        spaces = list(list_spaces(
            filter="mcp-server",
            sort="likes",
            direction=-1,
            limit=1000,
            full=True
        ))
        
        # Extract just the space IDs 
        space_ids = [space.id for space in spaces]
        
        # Cache results
        self.cache = space_ids
        self.cache_time = time.time()
        
        print(f"Found {len(space_ids)} MCP spaces")
        return space_ids

# Global instance
_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
    """
    
    # Get MCP spaces
    spaces = _finder.get_mcp_spaces()
    
    # Create dropdown with space choices
    dropdown = gr.Dropdown(
        choices=spaces,
        label=f"{dropdown_label} ({len(spaces)} available)",
        value=None
    )
    
    # Create textbox to display selection
    textbox = gr.Textbox(
        label=textbox_label,
        value=placeholder,
        interactive=False
    )
    
    # Connect dropdown to textbox
    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